Какой самый быстрый способ найти и удалить файлы?
С:
Find="$(find / -name "*.txt" )"
du -hc "$Find" | tail -n1
echo "$Find" | xargs rm -r
Если файл foo bar.txt
найден, он не будет считаться с помощью du или удалять файл. Что было бы лучшим способом избежать пробелов?
2 ответа
Если ни одно из ваших имен файлов не может иметь встроенные символы новой строки (что было бы очень необычно), вы можете использовать следующее:
Примечание. Чтобы предотвратить случайное удаление файлов во время экспериментов с командами, я заменил /
в качестве входных данных реж. (как используется в вопросе) с /foo
,
# Read all filenames into a Bash array; embedded spaces in
# filenames are handled correctly.
IFS=$'\n' read -d '' -ra files < <(find /foo -name "*.txt")
# Run the `du` command:
du -hc "${files[@]}" | tail -1
# Delete the files.
rm -r "${files[@]}"
Обратите внимание, что если вам не нужно забирать все имена файлов заранее и не против find
дважды, вы можете использовать один find
команда для каждой задачи (кроме передачи в tail
), который также является наиболее надежным вариантом (единственное предостережение в том, что если у вас есть так много файлов, что они не помещаются в одной командной строке, du
может быть вызван несколько раз).
# The `du` command
find /foo -name "*.txt" -exec du -hc {} + | tail -n1
# Deletion.
# Note that both GNU and BSD `find` support the `-delete` primary,
# which supports deleting both files and directories.
# However, `-delete` is not POSIX-compliant (a POSIX-compliant alternative is to
# use `-exec rm -r {} +`).
find /foo -name "*.txt" -delete
С помощью +
прекратить передачу команды -exec
имеет решающее значение, так как он наставляет find
передать столько совпадений, сколько поместится в одной командной строке целевой команде; как правило, но не обязательно, это приводит к единственному вызову; фактически -exec ... +
это как встроенный xargs
, за исключением того, что встроенные пробелы в аргументах не являются проблемой.
Другими словами: -exec ... +
не только надежнее, чем трубопровод xargs
, но - из-за отсутствия необходимости в конвейере и другой утилите - также более эффективен.
Возможно find / -name '*.txt' -exec du -hc {} \;
больше похоже на то, что вы ищете?
Но, делая это как вы, вы пропускаете кавычки в своем призыве к du
и без необходимости использовать xargs
когда это не сработает... Вы, кажется, влюблены в echo
кто не твой друг.
поскольку \0
не допускается в именах файлов, вы можете безопасно собирать результаты из find
используя его -print0
опция:
date > /private/var/mobile/Documents/Local\ Cookies/Clean
find . -print0 | while IFS='' read -r -d '' file
do
du -hc "$file" | tail -n 1
rm "$file"
done
Исправлено должно работать на MacOS и Linux сейчас.