Сортувати вихід знахідки -exec ls


14

Чи можливий вихід find … -exec ls -ls ;сортованого в алфавітному порядку за назвою файлу?

Це моя команда cron:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

Ця команда працює нормально, здебільшого. Але результати не відсортовані в жодній змістовної послідовності. Було б дуже корисно, якби вони були відсортовані за полем імені файлу.


1
Використовуючи zsh? ls -ls **/*(.)
Кевін

@Kevin Не зовсім - сортував lsби.
Жил "ТАК - перестань бути злим"

Відповіді:


14

Я припускаю, що ваші імена файлів не містять нових рядків.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

Використання +замість того, ;щоб припинити -execдію, прискорює процес виклику викликів ls. Ви можете сортувати, провівши sortкоманду; скажіть йому, щоб почати сортування у 10-му полі (перші 9 - це метадані: блоки, дозволи, кількість посилань, користувач, група, розмір та 3 поля дати / часу). Цей параметр -nповідомляє lsвикористовувати числові значення для користувача та групи, що дозволяє уникнути ризику імен користувачів або груп, що містять пробіли.

Крім того, за допомогою zsh ви можете піти, не припускаючи жодного імені, скориставшись глобальними класифікаторами для збору та сортування файлів та zargsзапуску lsдекількох разів, якщо командний рядок буде занадто довгим. Вам потрібен GNU ls(конкретно його -fваріант), щоб уникнути повторного сортування за ls(іншим підходом було б емуляція lszsh's zstat).

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf

Дуже дякую! Використання першої команди, яку ви надіслали, робить сортування. Чи буде все ще число 10, якщо я використовую коротший шлях? Наприклад, якщо я запускаю ту саму команду з / home / setefgge замість public_html?
14:29

@MaJ 10 - кількість пропущених полів, це не має нічого спільного з розміром імені файлу.
Жил "ТАК - перестань бути злим"

Дякую. Я ціную вашу допомогу, а також допомогу, яку надавали всі інші. Я вважаю цю проблему вирішеною. Тепер моя команда cron сортує файли. Це перший раз, коли я коли-небудь надсилав запитання до Stackexchange. Я не бачу варіанту "Розв’язаний". Якщо хтось із вас знає, як це зробити як вирішено, будь ласка, продовжуйте це робити. Спасибі!
14:19

@MaJ Найближче, що ми маємо відзначити питання як вирішене - позначити одну з відповідей як прийняту. Тільки ви, запитувач, можете це зробити. Для цього натисніть прапорець біля відповіді, яка вам найбільше допомогла. Якщо ви приймете відповідь, ви отримаєте ще 2 бали репутації, а після цього зможете оновити повідомлення; ви можете оприлюднити всі повідомлення, які вам здаються корисними. Для отримання додаткової інформації дивіться сторінку екскурсії та довідкову сторінку щодо того, що робити, коли хтось відповість на ваше запитання .
Жил 'ТАК - перестань бути злим'

1

Чому б не передати результат пошуку через сортування та не виконати ls для кожного з рядків?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done

1

POSIX має сказати про дати в ls -lсписку онг:

<date and time>Поле має містити відповідну дату і тимчасову мітку , коли в останній раз був змінений файл. У локалі POSIX поле повинно бути еквівалентом виводу наступної команди date:

date "+%b %e %H:%M"

... якщо файл було змінено за останні шість місяців, або:

date "+%b %e %Y"

Беручи це до уваги і гарантуючи, що якщо в імені файлу є якісь нові рядки, вони належним чином поширюються за допомогою вказаної також POSIX ls -qопції, підготувати регекс для lsрезультату порівняно просто find:

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

grepдля цього і ви повернете лише рядки, що містять рядки, що представляють або сьогоднішні, або вчорашні дати. Наступна команда додає до цього трохи:

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls варіанти складаються з:

  1. -a повернути всі файли в каталозі - включаючи ті, що починаються з a .dot
  2. -l довгий перелік
  3. -R рекурсивно перераховувати всі довідники
  4. -c відображення часу модифікації, а не часу доступу
  5. -qповерніть глобул оболонки, ?а не символи , що не друкуються або \tab, у назві файлу

Ці результати передаються через |pipeфайл, sedякому відповідають лише:

  1. Порожній рядок, що передує імені шляху, і наступний рядок
  2. Рядки, що починаються з - (іншими словами - не dдля каталогу), які також містять ваш date.
  3. Він не друкує рядки імен шляхів, окрім випадків, коли каталог, який вони називають, фактично містить файли, за якими ви фільтрували.

Вихід виглядає приблизно так:

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

Так, це навіть працює з цим, LS_COLORSщо, мабуть, є низьким пріоритетом для вашого cronкурсу, але, можливо , ваші варіанти відкриті.

У будь-якому випадку це дає значні переваги перед деякими іншими можливими рішеннями.

  1. В першу чергу find+ lsвключає кілька викликів - це включає лише один lsпроцес, і саме тому він може надійно сортувати все - що робиться за замовчуванням - і так sortсамо робиться допоміжним.

  2. Будь-яке рішення , що містить findі sortі lsв значній мірі робить все роботи в два рази. lsі findвони вирішать кожне ім'я шляху та statкожен файл. lsі sortобидва будуть сортувати всі результати. Напевно, найкраще замість цього просто використати сингл ls.

  3. Тоді, звичайно, є dateі sedчастина цієї відповіді. Що важливо зауважити, це те, що ви виконуєте важку частину і отримуєте регекс спочатку - і лише один раз -, а потім лише обрізаєте єдиний список результатів, а не скажете, отримуєте результати, отримуєте результати, сортуєте результати та сортуєте результати.

  4. Це не розбивається на назви файлів, що містять нові рядки, як, ймовірно, будуть інші рішення. У цього рішення є свої застереження - які я поясню далі - але вони є незначними та легко обробляються. На мою думку, це найбільш міцне рішення тут.

Є два випадки, коли вищевказана команда може викликати у вас проблеми. Перший стосується ?глобусів у назви файлів - хоча це вже більш надійне рішення, ніж будь-яке інше, що пропонується тут, і ймовірність того, що ви зіткнетеся з ані ?зовсім невеликою, існує ймовірність, що вирішити ці кулі може відповідати більше ніж одне ім’я файлу. Будь ласка, дивіться це для отримання додаткової інформації з цього приводу.

Інша можливість передбачає помилковий позитив - наприклад, якщо у вас є ім'я файлу, що фактично відповідає dateрядку, за яким ми шукаємо, grepале фактично не було змінено жодного з цих днів. Я не розраховую на те, що це проблема, але, якщо вона є, запитайте про це, і я, мабуть, можу допомогти вам зробити регулярний вираз більш детальним, щоб вирішити це.


0

Ви можете використовувати комбінацію знахідки, xargs та ls.

Ось зразок команди: find . -type f -print0 | xargs -0 ls -lt

  • find буде рекурсивно шукати всі файли в поточному каталозі.
  • xargs передасть цей список файлів lsкоманді за один виклик (за умови findповернення менше, ніж ARG_MAXфайлів).
  • ls -lt буде сортувати ці файли за часом та форматувати вихід

Щоб завантажити систему, ARG_MAXви можете ввести:

$ getconf ARG_MAX
> 2621440

-1
ls -l $(find /home/setefgge/public_html -type f -ctime -1 | sort)

1
lsробить власне сортування, тому трубопровід виводу findчерез sortє марним. Крім того, ваша команда обробляє імена файлів, що містять пробіли (серед інших), і вони вийдуть з ладу, якщо буде занадто багато імен файлів.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.