
Я пытаюсь переместить файлы следующим образом:
...
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
...
в соответствующие папки, например: переместить файл в папку, на dialogue023/
которую он начинается с DLG023
; в dialogue024/
папку, на которую он начинается с DLG024
; и т. д.
Все файлы и каталоги находятся на одном уровне.
Другими словами, я пытаюсь создать команды вроде этой:
mv DLG023-00-01-sprite.ogg dialogue023/
Как извлечь первую цифру из имени файла?
Пока у меня получилось вот что:
for i in DLG*-*-*-sprite.ogg; do echo "${i//[^0-9]}";done
Но это выводит все цифры (например, 230001), когда мне нужна только первая (например, 23).
решение1
-t
Я предполагаю, что вы используете OS X, в которой нет такой возможности 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
если результат вас удовлетворит, выполните следующие действия.
решение2
Вы можете сгенерировать команду 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
решение3
Однолинейное решение с использованием 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"'
перемещает файл в этот каталог.
решение4
Пара идей:
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