Как вывести список файлов старше дня с «2015» в имени файла?


11

Я хочу перечислить все файлы журнала, которые не принадлежат сегодня, и только те файлы, которые содержатся 2015в их именах.

Это команды, которые я пробовал:

find . -name 2015 -mtime +1 -exec  ls -ltrh  {} \;
find . -name *2015* -mtime +1 -exec  ls -ltrh  {} \;

Вывод из обоих ничего, но, тем не менее, файлы есть. Что-то не так с этими командами, и я не понимаю, что. Любая помощь будет оценена.


findЧасть выглядит хорошо для меня, но я также имел проблемы с -execпараметром. Я не мог заставить это работать тоже. (Я пытался переместить все файлы jpg из одной папки в родительский каталог через нее - и в итоге я сделал это вручную ...)
Byte Commander


@steeldriver Я думаю, что это действительно так, потому что если бы в текущем каталоге были файлы с 2015их именем (другой очевидный недостаток в написании команды), я подозреваю, что будет какой- то вывод. Так что вы можете опубликовать ответ об этом.
Элия ​​Каган,

Ответы:


18

Команда find . -name '*2015*' -mmin +1440 -ls, вероятно, сделает то, что вы хотите. Смотрите ниже для деталей.

Ваша первая команда имела -name 2015. Это не сработало, потому что он находит только файлы, чьи имена точно 2015 , без других символов в них.

Ваша вторая команда, find . -name *2015* -mtime +1 -exec ls -ltrh {} \;возможно, потерпела неудачу по нескольким причинам:

1. Символы без кавычек *расширяются оболочкой, а затем передаются в find.

Если есть какие-либо файлы, непосредственно содержащиеся в текущем каталоге (тот, в котором вы находились, когда вы запускали эту find ...команду), чьи имена содержат 2015(и не начинаются с .), то оболочка расширяется *2015*до списка этих имен файлов, а затем передается этот список в качестве аргументов find. Это не то, что вы хотите - вместо этого вы хотите передать *2015*буквально в качестве аргумента для поиска, чтобы find, а не оболочка, могла найти, какие файлы соответствуют ей.

Чтобы решить эту проблему, процитируйте *2015*. Есть три распространенных способа сделать это:

  • '*2015*'(т.е. find . -name '*2015*' -mtime +1 -exec ls -ltrh {} \;)
  • "*2015*"(т.е. find . -name "*2015*" -mtime +1 -exec ls -ltrh {} \;)
  • \*2015\*(т.е. find . -name \*2015\* -mtime +1 -exec ls -ltrh {} \;)

Я предлагаю писать его в одинарные кавычки , как '*2015*', потому что:

Но в этом случае это не имеет значения. 'и "оба обрабатывают *одно и то же, и выражение недостаточно сложное для \цитирования, чтобы его было трудно понять.

2. -mtime +1только выбирает файлы, измененные два или более дней назад.

Как man findговорит:

       Numeric arguments can be specified as

       +n     for greater than n,

       -n     for less than n,

       n      for exactly n.
       -mtime n
              File's data was last modified n*24 hours ago.  See the  comments
              for -atime to understand how rounding affects the interpretation
              of file modification times.
       -atime n
              File was last accessed n*24 hours ago.  When  find  figures  out
              how  many  24-hour  periods  ago the file was last accessed, any
              fractional part is ignored, so to match -atime +1, a file has to
              have been accessed at least two days ago.

Предположим, файл был изменен 47 часов назад. Для того, чтобы выяснить , сколько 24-часовые периоды , то есть findраунды вниз : это один 24-часовой период назад. Но -mtime +1подходит только для файлов, время модификации которых строго больше 24 часов назад. Таким образом, файлы со вчерашнего дня не совпадают.

См. Почему find -mtime +1 возвращает только файлы старше 2 дней? для получения дополнительной информации, как предложено Steeldriver .

Чтобы найти файлы , измененные в любое время более 24 часов назад , я предлагаю вместо оговаривая это как 1440 минут назад с -mmin +1440:

find . -name '*2015*' -mmin +1440 -exec ls -ltrh {} \;

Некоторым читателям может быть интересно, почему я не цитирую {}. Некоторые люди цитируют, {}чтобы напомнить людям, что это не выражение для расширения скобки . Оболочки в стиле Bourne (например, bash ) не требуют, чтобы {}внутри них было что-либо цитироваться. Может быть, какая-то оболочка не в стиле Борна обрабатывает это специально; возможно, поэтому некоторые пользователи цитируют его. Но есть также заблуждение, что иногда нужно заключать в кавычки, {}чтобы -execправильно обрабатывать имена файлов с пробелами. Это, с ложным: с {}или '{}', findполучает те же аргументы, как оболочка удаляет кавычки перед переходом '{}'кfind, Чтобы противостоять этому заблуждению, я не цитирую {}, но это вопрос стиля - если вы предпочитаете {}документировать, как оболочка не обрабатывается {и }особенно, это нормально.

Я рекомендую вам также либо изменить lsкоманду, или (как Muru предложил ) заменить его find«S -lsдействия. ls -ltrhвероятно , не делать то , что вы собираетесь , так как он выполняется отдельно для каждого найденного файла и , следовательно, -tи -rфлаги, которые определяют сортировку, не имеют никакого отношения.

Хотя вывод будет отформатирован немного иначе, чем с ls -lиспользованием, использовать -lsпроще и проще.

find . -name '*2015*' -mmin +1440 -ls

Или, если вы решите, что вам действительно нужно только перечислить имена файлов (включая их пути, относительно .), вы можете просто указать бездействие, вызывая -printдействие по умолчанию :

find . -name '*2015*' -mmin +1440

1
Хороший подробный ответ! по крайней мере в GNU find есть newerXYсинтаксис, который принимает аргументы календаря, например, -newermt 'yesterday'и! -newermt 'yesterday'
steeldriver

Знаешь что ? Вы великолепны. @ Eliah Kagan
r 8dʒɑ

Спасибо Stell Driver, это очень хорошая информация по ссылке, чтобы знать. Но в моем случае, так как это журнал приложений из старых файлов, модифицировать его было невозможно.
Еще

2

Процитируйте выражение, и я предлагаю вам также заключить в скобки

find . -name "2015" -mtime +1 -exec  ls -ltrh  '{}' \;

или

find . -name "*2015*" -mtime +1 -exec  ls -ltrh  '{}' \;

вам не нужно передавать найденные файлы в ls

find . -name "*2015*" -mtime +1

Может быть, ограничить использование -type f? И если lsнужно использовать, предложите использовать -ls.
Муру

1
Конечно, все хорошие предложения. Я не уверен, чего хочет ОП, и считаю, что источником проблемы является отсутствие кавычек вокруг шаблона поиска "-name".
Пантера

2

В zsh вы можете использовать глобальные квалификаторы (это уникальная функция zsh, недоступная в других оболочках, таких как bash).

ls -ltr *2015*(m+1)

Это только список файлов в текущем каталоге; для рекурсивного обхода каталогов используйте

ls -ltr **/*2015*(m+1)

С find, -name 2015только находит файлы, чье имя точно 2015. -name *2015*работает только в том случае, если нет файлов, чье имя содержится 2015в текущем каталоге, потому что оболочка расширяет шаблон *2015*перед findвызовом. Вам нужно процитировать шаблон:

find -name '*2015*' -mtime +1 …

Обратите внимание, что оба find -mtime +1и zsh *(m+1)находят файлы, возраст которых не менее 48 часов , а не файлы старше, чем сегодня. Знак плюс означает «строго больше чем», а количество дней округляется в меньшую сторону. Чтобы найти файлы, которым не менее 24 часов, используйте -mtime +0или (m+0).

Если вы хотите найти файлы, которые были последний раз изменены вчера или ранее , вы можете использовать findс -newermtпредикатом :

find -name '*2015*' ! -newermt 'today 0:00' …

Там действительно нет удобного способа сделать этот тест в Zsh.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.