Как удалить несколько файлов с общим префиксом и суффиксом?

21

У меня есть много файлов с именем

sequence_1_0001.jpg  
sequence_1_0002.jpg  
sequence_1_0003.jpg  
...

и файлы с именем

sequence_1_0001.hmf  
sequence_1_0002.hmf  
sequence_1_0003.hmf  
...

и файлы с именем

sequence_2_0001.jpg  
sequence_2_0002.jpg  
sequence_2_0003.jpg  
...

а также

sequence_2_0001.hmf  
sequence_2_0002.hmf  
sequence_2_0003.hmf  
...

Я просто хочу удалить файлы, которые начинаются с 'sequence_1' и заканчиваются на '.hmf', но я не хочу удалять их один за другим, поскольку существуют тысячи файлов. Как мне указать команде rm, что я хочу удалить все, которые начинаются с префикса 'sequence_1' и заканчиваются на '.hmf'?

В настоящее время я работаю с системой RedHat Linux, но я хотел бы знать, как это сделать и в других дистрибутивах.

Павел
источник

Ответы:

28
rm sequence_1*.hmf

удаляет файлы , начиная с sequence_1и заканчивая .hmf.


Глобализация - это процесс, в котором ваша оболочка берет шаблон и расширяет его в список имен файлов, соответствующих этому шаблону. Не путайте это с регулярными выражениями, которые отличаются. Если вы проводите большую часть своего времени в bashWooledge Wiki, у вас есть хорошая страница о глобализации (расширение пути) . Если вам нужна максимальная переносимость, вам также следует прочитать спецификацию POSIX о сопоставлении с образцом .


В маловероятном случае, если вы столкнетесь с ошибкой «Список аргументов слишком длинный» , вы можете взглянуть на BashFAQ 95 , в котором это исправлено . Самый простой обходной путь - разбить шаблон глобуса на несколько более мелких кусков, пока ошибка не исчезнет. В вашем случае, возможно, вам не удастся разделить совпадение по префиксным цифрам от 0 до 9 следующим образом:

for c in {0..9}; do rm sequence_1_"$c"*.hmf; done
rm sequence_1*.hmf  # catch-all case
jw013
источник
Это очень умная работа с ошибкой «список аргументов слишком длинный». В моем случае у меня двадцать тысяч файлов, поэтому я думаю, что мне придется использовать цикл for с 0, .., 20. Правильно?
Пол
@Paul Правильно, просто разбейте список на столько кусков, сколько вам нужно, хотя в какой-то момент findподход становится проще, чем угадывать и проверять.
jw013
14

Хотя ответ jw013 является правильным по отношению к глобализации, эта команда может потерпеть неудачу, если у вас есть тысячи совпадений: расширенная командная строка, rm sequence_1_0001.hmf sequence_1_0002.hmf ...сгенерированная оболочкой, может быть просто слишком большой.

Как предложил Dom, вы также можете использовать -deleteопцию с find:

find . -maxdepth 1 -type f -name 'sequence_1*.hmf' -delete

И то, -maxdepthи другое -delete, хотя и не входит в стандарт POSIX , довольно часто встречаются в findреализациях на свободе. В дистрибутивах Linux обычно используется GNU find, который, безусловно, поддерживает эти опции.

Бесполезный
источник
2
Если вы можете, используйте опцию -delete для поиска, она не разворачивается для каждого файла ...
Dom
Добавлено, ура. Похоже, -deleteдолжно поддерживаться в последних системах GNU и BSD, пока -print0только для GNU. Так что он, вероятно, более переносим (хотя это не должно иметь значения для ОП).
бесполезно
По крайней мере, в OS X find есть -print0, но она не включена в POSIX.
Лри
5
rm sequence_1_{0000..0999}.hmf
rm sequence_1_{1000..1999}.hmf
rm sequence_1_{2000..2999}.hmf
...

будет работать тоже в Bash.

неизвестный пользователь
источник
Расширение скобок требует bash, и я считаю, что для формы с нулевой подкладкой нужна версия 4.
jw013