Как использовать sed для удаления шаблона временной метки из списка имен файлов с нулевым завершением

Для поиска файлов старше последней 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

6
задан 23 December 2020 в 12:18

3 ответа

Преобразование двух процессов 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] * // , который удаляет строку , соответствующую регулярному выражению.

4
ответ дан 3 January 2021 в 22:48

Вы можете использовать команду 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
3
ответ дан 3 January 2021 в 22:48

Поскольку вы управляете выводом, очень легко удалить временные метки. Вы знаете, что каждая запись с обозначением \ 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/^[^ ]* //'
5
ответ дан 3 January 2021 в 22:48

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

Похожие вопросы: