2

Я хочу удалить все файлы в текущем каталоге и подкаталогах, имя файла которых превышает определенную длину.

Есть ли простой способ сделать это из Bash?

2 ответа2

4

Вы можете использовать find чтобы найти все файлы в текущем каталоге и подкаталогах, затем измерить длину имени файла с помощью bash и удалить соответственно:

$ find . -type f | while IFS= read -r file; do 
    ## find will return the full path, strip the
    ## path from the file name. 
    name=$(basename "$file"); 
    ## Check the name'slength and delete if > 5
    [ "${#name}" -gt 5 ] && rm "$file"; 
  done

Кроме того , вы можете сделать все , что от find с помощью -regex и -delete Например, чтобы удалить имя файла длиной более 5 символов (исключая путь):

find . -type f -regextype posix-egrep -regex '.*[^/]{5}' -delete
3

Вы уже предоставили команду find которая безопасна для файлов со странными именами:

find -regextype posix-egrep -type f -regex '.*[^/]{5}' -delete

Это регулярное выражение соответствует пяти конечным символам, которые не содержат косую черту (т. Е. Имя файла длиннее пяти символов).

Предоставленный вами цикл Bash, как правило, будет работать, но он, вероятно, не масштабируется с тысячами файлов и может разрываться с использованием специальных имен файлов.

Альтернатива, которая похожа по эффективности, но может обеспечить большую гибкость (замените rm на -n1 echo для печати всех файлов):

find -type f -print0 | grep -Ez '[^/]{5}$' | xargs -0 rm

-print0 , -z и -0 гарантируют, что каждое имя файла оканчивается байтом NUL. Это гарантирует, что специальные символы не разделяют имена файлов (новые строки нарушают предоставленную вами команду Bash). Хотя эта grep command все еще не выполняется с именем, например path/abc\ndef (где \n - новая строка ), она не будет разбита на path/abc и def .

Поскольку вы редко найдете файлы с \n в названии, я оставляю реализацию для этого случая в качестве упражнения для читателя.

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