Як перелічити файли, старші ніж на добу, у назві файлу "2015"?


11

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

Це команди, які я спробував:

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

Вихід з обох нічого, але все ж файли є. Щось із цими командами не так, і я нічого не отримую. Будь-яка допомога буде вдячна.


findЧастина виглядає добре для мене, але я також мав проблеми з -execпараметром. Я не міг так працювати. (Я намагався перемістити всі jpg-файли з однієї папки в його батьківський каталог через неї - і в кінцевому підсумку це робив вручну ...)
Байт-командир


@steeldriver Я думаю, що тут дійсно не так, оскільки якби в поточному каталозі були файли з 2015їх іменем (інший очевидний недолік способу написання команди), я підозрюю, що буде якийсь вихід. Тож ви можете опублікувати відповідь на це.
Eliah Kagan

Відповіді:


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

Див. Чому знаходить -mtime +1 лише повернення файлів, старших 2 днів? для отримання додаткової інформації, як запропонував steeldriver .

Щоб знайти файли , змінені в будь-який час більше 24 годин тому , я пропоную замість обумовлюючи це як 1440 хвилин тому з -mmin +1440:

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

Деяким читачам може бути цікаво, чому я не цитував {}. Деякі люди цитують, {}щоб нагадати людям, що це не вираз для розширення дужок . Раковини в стилі Борна (як баш ) не вимагають, щоб {}нічого не містилося всередині. Можливо, якась оболонка в не-Борні дійсно стосується цього; тому деякі користувачі це цитують. Але є також помилкова думка, що іноді треба цитувати, {}щоб -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 знайти, є також newerXYсинтаксис, який приймає аргументи календаря, наприклад, -newermt 'yesterday'і! -newermt 'yesterday'
steeldriver

Знаєш, що ? Ви приголомшливі. @
Eliah

Дякую водію Stell, це дуже хороша інформація за посиланням, щоб знати. Але в моєму випадку, оскільки це журнал додатків із старих файлів програми, неможливо змінити. Дякую ще раз
rɑːdʒɑ

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.
muru

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.