Командний конвеєр після трубопроводу xargs


38

HP-UX ***** B.11.23 U ia64 **** необмежена ліцензія користувача

find . -type d -name *log* | xargs ls -la

дає мені імена каталогів (ті, що містяться logв імені каталогу), а потім усі файли в цьому каталозі.

Каталоги  /var/opt/SID/application_a/log/,  /var/opt/SID/application_b/log/,  /var/opt/SID/application_c/log/і так далі містять файли журналів.

Я хочу, щоб тільки два останні логіни були перелічені lsкомандою, яку я зазвичай знаходжу за допомогою ls -latr | tail -2.

Вихід повинен бути чимось подібним ..

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2не дає мені вищезазначеного результату. Я отримую список останніх двох файлів find . -type d -name *log* | xargs ls -laкоманд.

Тож чи можу я передавати команди після трубопроводу xargs? Як ще я запитую, щоб отримати результуючий список файлів у наведеному вище форматі?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

дає мені список з десяти імен каталогів у поточному каталозі, який трапляється, /var/opt/SIDі це теж не те, що я хочу.


2
Вам слід процитувати, *log*інакше оболонка розширить його.
Антон

Майте на увазі, що sh -cочікує, що ім'я команди (параметр 0) є другим аргументом, тому завжди слід це робити find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(зауважте lstailв кінці, який буде служити $0для створеної оболонки). Інакше перший із ваших результатів заповнить цю роль і не використається.
Йонас

Відповіді:


58

Ви майже там. У вашій останній команди, ви можете використовувати , -Iщоб зробити lsправильно

-I replace-str

    Замініть випадки заміщення str у початкових аргументах іменами, прочитаними зі стандартного вводу. Крім того, пропуски без котирування не закінчують елементи введення; натомість роздільник - символ нового рядка. Наслідки -xі -L 1.

Отже, с

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

Ви echoзнайдете режисера find, потім зробіть ls | tailце.


знайти. -типу d -імення " log " | xargs -I {} sh -c "echo {}; ls -ltr {} | grep -E \" file_in | file_out \ "| хвіст -5" Я використав цей.
інша

3
Я зxargs -n 1 sh -c 'echo $0'
Ginhing

1
на macOS заміна не працювала в рамках цитованої команди, тому echo $0була корисною (і зрозуміліше)
mpuncel

1
Для того, щоб змусити його працювати з іменами файлів з пробілами, використання -print0, xargs -0і бігти {}в подвійні лапки всередині в shкоманді:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
Бенедикту Köppel

Я використовую ехо "xargs -n 1 sh -c" \ $ 0 | $ func "` якщо мені потрібно використовувати змінну $ func
бог


2

Просто на додаток до fredtantini і як загальне уточнення (оскільки документи трохи заплутані):

xargs -I {}Прийматиме «{}» символи зі стандартного вводу і замінити їх з тим, що надходить з труби. Це означає, що ви насправді можете замінити {}будь-яку комбінацію символів (можливо, щоб краще відповідати бажаному програмовому аромату). Наприклад : xargs -I % sh -c "echo %". Якщо ви завжди використовуєте, xargs -I {}ви можете замінити його xargs -iтаким, як це скорочення.

sh -cПокаже ваш Баш / оболонку , щоб прочитати наступну команду з рядка , а не зі стандартного вводу. Тож писати sh -c "echo something"рівносильно echo something.

xargs -I {} sh -c "echo {}"Читатиме введення створених з допомогою sh -cякої є echo {}. Оскільки ви сказали це замінити {}аргументами, які ви отримали з труби, саме так і станеться.

Ви можете легко протестувати це навіть без трубопроводів, просто введіть вищезгадану команду в термінал. Що ви напишете далі, виведете на термінал (Ctrl-D для виходу).

У ls -la {}команді те ж саме відбувається знову. Значення {}замінюється вмістом команди "попередня труба".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.