Как «rm» или «mv» диапазон файлов, таких как file01.txt, file02.txt… file85.txt

23

Предположим, у меня есть несколько файлов с таким именем:

file01.txt file02.txt file03.txt ... file20.txt

и я хочу выполнить команду для диапазона этих файлов.

Я знаю, что если я хочу «rm» из «file05.txt» в «file09.txt», я могу сделать:

rm file0[5-9].txt

но как я могу 'rm' диапазон от file08.txt до file13.txt? Я пробовал этот код

rm file[08-13].txt

и это не работает. Я мог бы запустить эту команду:

rm file0[89].txt file1[0-3].txt

но я хотел бы знать, смогу ли я сделать это только с одним уточненным аргументом 'rm', если это возможно.


источник
Здесь был дан почти идентичный вопрос: stackoverflow.com/questions/25049411/…
arielf

Ответы:

38

Вам нужно использовать скобку расширения bash:

rm file{08..13}.txt

Это удалит файлы file08в file13, покажет сообщение об ошибке, если какой-либо файл отсутствует.

Установите диапазон, чтобы удовлетворить ваши потребности.


Проблема с оператором globbing []заключается в том, что он обрабатывает каждый символ / цифру внутри него как один токен и поэтому поддерживает только объявление диапазона с использованием одной цифры.

Если вы настаиваете на использовании [], вы можете использовать это довольно уродливый рисунок в матче file08с file13:

rm file0[8-9].txt file1[0-3].txt
heemayl
источник
5
Расширение скобок также полезно с запятыми, как для mv foo.{txt,md}илиcp foo.txt{,.bak}
Кос
2

Некоторые оболочки, такие как Ubuntu по умолчанию /bin/sh(то есть dash) или mkshне имеют расширения скобок, или в случае kshрасширения скобок не могут использовать дополненные нули:

$ ksh -c 'echo {05..13}'
5 6 7 8 9 10 11 12 13

В таких случаях мы можем использовать printfдля форматирования числовой части имени файла и использовать цикл while для реализации c-like для поведения цикла (обратите внимание, чтобы заменить echoна rmили как хотите):

$ i=5; while [ "$i" -le 10 ]; do num=$(printf "%.2d" "$i" ); echo "file$num.txt";i=$(($i+1)); done
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

И это достаточно портативный - работает с dash, ksh, mksh, и bash. В случае kshи bashмы также можем использовать c-style for loop syntax (but not in case ofmksh ordash`):

$ ksh -c 'for((i=5;i<11;i++)); do num=$(printf "%.2d" "$i" ); echo "file$num.txt";done'             
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

Обратите внимание, что в этом bashслучае printfподдерживается печать в переменную, и, следовательно, мы могли бы сделать printf -v num "%.2d" "$i"вместо использования подстановки команд.

Сергей Колодяжный
источник