Я хочу удалить все файлы в текущем каталоге и подкаталогах, имя файла которых превышает определенную длину.
Есть ли простой способ сделать это из Bash?
Я хочу удалить все файлы в текущем каталоге и подкаталогах, имя файла которых превышает определенную длину.
Есть ли простой способ сделать это из Bash?
Вы можете использовать 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
Вы уже предоставили команду 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
в названии, я оставляю реализацию для этого случая в качестве упражнения для читателя.