Извлечь из man find
:
-print0
True; выведите полное имя файла на стандартный вывод, с последующим нулевым символом (вместо символа новой строки, который использует -print). Это позволяет программам, обрабатывающим вывод find, правильно интерпретировать имена файлов, содержащие символы новой строки или другие типы пробелов. Этот параметр соответствует параметру -0 в xargs.
Итак, если (например) вы хотите найти и удалить файлы старше последних 10 в каталоге, вы можете использовать (кредит @pLumo):
find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | xargs -0 gio trash
Но как бы вы подсчитали количество файлов, которые должны быть удалены перед этой командой?
Используйте grep
, который может обрабатывать строки, разделенные нулевыми символами:
find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | grep -zc .
Из man grep
:
-z, --null-data
Treat input and output data as sequences of lines, each terminated by a zero byte
(the ASCII NUL character) instead of a newline. Like the -Z or --null option, this
option can be used with commands like sort -z to process arbitrary file names.
Так что, если (например) вы хотите найти и удалить в каталоге файлы старше 10 последних, вы можете использовать ...
Нет, вы не могли. find
не гарантирует, что выходные данные будут в порядке создания, модификации, доступа или чего-либо еще в этом отношении (за исключением того, что есть упорядочение по -depth
, но это ни здесь, ни там).
Вам понадобится что-то вроде:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -Vrz | sed -z '1,10d; s/^[[:digit:].]* //'
, которое использует время модификации (печатается как метка времени Unix с использованием % T @
, и сортирует этим, используя сортировку версии -V
в качестве прокси для общей сортировки с плавающей точкой, а затем, наконец, удаляет метку времени, используя sed
.
Создать индексный массив с файлами в порядке убывания; самый новый файл с индексом 0 или ls -rt
, который упорядочит файлы в порядке возрастания.
$ eval "a=($(ls -t --quoting-style=shell-escape))"
Вывести из n-го файла в конец:
(используя нисходящий массив со смещением | - - | xxxx |
предотвратит, например, цикл от случайного поглощения ваших файлов).
$ printf %s\\n "${a[@]:10}"
Печать с начала в n-й файл:
$ printf %s\\n "${a[@]:0:10}" # or "${a[@]::10}"
^ ^
offset length
Печать n-го файла с начала:
$ printf %s\\n "${a[@]:5:1}"
печать n-го файла с конца:
$ printf %s\\n "${a[@]:(-5):1}"
Вывести список файлов с нулевым символом в конце:
$ printf %s\\0 "${a[@]:10}" | xargs -0 -n 1
Пример сценария, как вы можете использовать его в цикле;
#!/bin/bash
eval "a=($(ls -t --quoting-style=shell-escape))"
for b in "${a[@]:10}"; do
ls "$b"
done
Оставьте прежним Выведите строку и напечатайте количество файлов после их удаления:
find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | xargs -0 bash -c 'gio trash $*;echo $# files trashed'
Или вы можете подсчитать количество строк независимо друг от друга. Просто вернитесь к обычному концу строки ( print
вместо print0
и удалив -z
).
find . -maxdepth 1 -type f -print | sort -r | sed 1,10d | wc -l