2

Я пытаюсь переместить файлы так:

...
DLG023-00-01-sprite.TextGrid.json
DLG023-00-01.prosody.json
DLG023-01-01-sprite.ogg
DLG023-00-02-sprite.TextGrid.json
DLG023-00-02.prosody.json
DLG023-01-02-sprite.ogg
...
DLG028-00-01-sprite.TextGrid.json
DLG028-00-01.prosody.json
DLG028-01-01-sprite.ogg
...

в соответствующие папки, например: переместите файл в dialog023 dialogue023/ когда он начинается с DLG023 ; к диалогу 024 dialogue024/ когда он начинается с DLG024 ; и так далее.

Все файлы и каталоги находятся на одном уровне.

Другими словами, я пытаюсь создать такие команды:

mv DLG023-00-01-sprite.ogg dialogue023/

Как я могу извлечь первое число из имени файла?

Пока у меня есть это:

for i in DLG*-*-*-sprite.ogg; do echo "${i//[^0-9]}";done

Но при этом выводятся все цифры (например, 230001), когда мне нужна только первая (например, 23).

4 ответа4

1

Я предполагаю, что вы используете OS X, у которой нет опции -t в mv . Это будет мучительно медленно, если скрипт обрабатывает тысячи файлов.

    for file in DLG*; do
    # Extract the three digits after DLG
    getnum=${file%%-*}
    getnum=${getnum#???}

    # make the directory dialogue### or exit if there is an error
    echo mkdir -p "dialogue${getnum}" || exit

    echo mv "$file" "dialogue${getnum}"
    done

Удалите echo перед mkdir и mv если вывод является удовлетворительным.

0

Пара идей:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i//[^0-9]}" | head -c 2; echo ;done

Если вы уверены, что они все одинаковой длины:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i:3:3}" ;done
0

Вы можете сгенерировать команду mv используя это:

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done

Теперь команда печатается так:

mv "DLG023-00-01.prosody.json" "dialogue023/"
[...]
mv "DLG028-00-01.prosody.json" "dialogue028/"
[...]

Если это то, что вы хотите, просто передайте этот вывод bash и он будет выполнен:

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done | bash
0

Одно строчное решение с использованием find:

find . -name DLG* -exec bash -c 'DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/"); mkdir "$DEST"; mv "$0" "$DEST"' {} \;
  • команда find ищет файлы DLG* из этого каталога.
  • Для каждого результата выполните предложение bash -c .

В предложении bash :

  • DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/"); выбирает каждый результат из find ($0) и, используя sed заменяет все числа перед первым - (DLG ([0-9]+) -. *) на dialogue следующий за этими числами (dialogue\1), и вставляет переменную называется DEST .
  • mkdir "$DEST" создает необходимую папку.
  • mv "$0" "$DEST"' перемещает файл в этот каталог.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .