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

10

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

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

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

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

    
задан Ten-Coin 08.04.2015 в 01:11
источник

3 ответа

18

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

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

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

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

Если в директории current (той, с которой вы работаете, когда вы запустили эту команду find ... ) есть файлы, имена которых содержат 2015 (и не начинаются с a . ), затем shell расширил *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 {} \; )

I предложите записать с одинарными кавычками как '*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-часовой период назад. Таким образом, файлы со вчерашнего дня не совпадают.

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

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

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

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

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

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

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

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

find . -name '*2015*' -mmin +1440
    
ответ дан Eliah Kagan 08.04.2015 в 03:33
источник
2

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

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

или

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

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

find . -name "*2015*" -mtime +1
    
ответ дан Panther 08.04.2015 в 01:38
2

В zsh вы можете использовать glob qualifiers (это уникальная функция 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.

    
ответ дан Gilles 08.04.2015 в 14:37