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

С:

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 сейчас.

Другие вопросы по тегам