Для поиска файлов старше последней 8 Я используя:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rz | sed -z 1,8d
Команда -printf '% T @% p \ 0'
применяет последнюю измененную отметку времени (выраженную в секундах с 1 января 1970 г., 00: 00 GMT, с дробной частью) до начала каждого совпадающего файла с завершающим нулем , например:
1597765267.7628475560 ./fileName2.txt1597765264.0267179360 ./fileName1.txt
Чтобы удалить эти самые старые файлы по конвейеру в xargs -0 gio trash
, Мне нужно удалить временные метки . Для этого я добавляю еще одну команду sed:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rz | sed -z 1,8d | sed -z "s/^[0-9]*.[0-9]* //g"
Теперь у меня правильный результат, но есть ли более эффективный способ?
На основе @ Ответ Quasímodo: я попытался еще больше упростить, используя формат шаблона удаления sed (поскольку я фактически ничего не заменяю), но я не получил результата:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,8d; /^[0-9]*\.[0-9]* /d"
Все предложения приняты с благодарностью.
Заключение (из нескольких ответов ):
find $targetPath -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,${retain}d; s/^[^ ]* //"
Где : [11 54513]
$ targetPath, Каталог для поиска файлов, например текущий каталог '.'
$ {keep}, количество самых новых файлов для сохранения, например 8
Преобразование двух процессов Sed в один.
sort -zrn | sed -z "1,8d; s/^[0-9]*\.[0-9]* //"
Внесенные исправления:
n
числовую сортировку. .
соответствует любому символу, это должно быть \.
в регулярном выражении. g
заменяет все совпадения в записи. Вам потребуется только одна подстановка (а именно удаление отметки времени) из каждой записи, поэтому удалите этот g
. Эта модификация также улучшает производительность. Ваша попытка sed -z "1,8d; /^[0-9 ]*\.[0-9 sizes* / d"
терпит неудачу, потому что / ^ [0-9] * \. [0-9] * / d
удаляет каждую строку , соответствующую регулярному выражению. Это отличается от s / ^ [0-9] * \. [0-9] * //
, который удаляет строку , соответствующую регулярному выражению.
Вы можете использовать команду find
с GNU awk
:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -zrn | awk 'BEGIN{RS=ORS="\0"} NR>8 {sub(/[^ ]+ /, ""); print}'
Здесь:
Мы устанавливаем разделитель входных записей ( RS
) и разделитель выходной записи ( ORS
) на \ 0
.
Для каждой записи, начиная с 8-й записи ( NR> 8
), мы заменяем все до первого пробела, включая первое пробел, пустой строкой ( sub (/ [^] + /, "")
) и печатаем запись ( print
). Спасибо @Quasimodo за предложение улучшений для указанной выше команды.
Пример:
$ touch {01..15}.txt
$ ls
01.txt 02.txt 03.txt 04.txt 05.txt 06.txt 07.txt 08.txt 09.txt 10.txt 11.txt 12.txt 13.txt 14.txt 15.txt
$ find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -zrn | awk 'BEGIN{RS=ORS="\0"} NR>8 {sub(/[^ ]+ /, ""); print}'
./07.txt./06.txt./05.txt./04.txt./03.txt./02.txt./01.txt
Поскольку вы управляете выводом, очень легко удалить временные метки. Вы знаете, что каждая запись с обозначением \ 0
начинается с отметки времени, а затем с пробела. Поэтому все, что вам нужно сделать, это удалить все непробельные символы до первого пробела:
find . -maxdepth 1 -type f -printf '%T@ %p\0' |
sort -rz | sed -z '1,8d; s/^[^ ]* //'
Однако вам, вероятно, нужна числовая сортировка, и вы также можете сортировать только по первому полю, не нужно также сортировать по имени файла. Итак, это даст вам 8 самых старых файлов:
find . -maxdepth 1 -type f -printf '%T@ %p\0' |
sort -rznk1,1 | sed -z '1,8d; s/^[^ ]* //'