Я роблю, find
а потім отримую список файлів. Як я передаю його іншій утиліті cat
(наприклад, щоб кішка відображала вміст усіх цих файлів) і в основному потрібно grep
щось із цих файлів.
Я роблю, find
а потім отримую список файлів. Як я передаю його іншій утиліті cat
(наприклад, щоб кішка відображала вміст усіх цих файлів) і в основному потрібно grep
щось із цих файлів.
Відповіді:
Перехід до іншого процесу (Хоча НЕ БУДЕ виконати те, що ви сказали, що намагаєтесь зробити):
command1 | command2
Це надішле висновок command1 як вхід command2
-exec
на a find
(це зробить те, що ви хочете зробити - але конкретно для find
)
find . -name '*.foo' -exec cat {} \;
(Все між find
і -exec
є предикатами знаходження, які ви вже використовували. {}
Замінить конкретний файл, який ви знайшли в команді ( cat {}
в даному випадку); команду \;
слід закінчити -exec
.)
відправити вихід одного процесу як аргументи командного рядка на інший процес
command2 `command1`
наприклад:
cat `find . -name '*.foo' -print`
(Зверніть увагу , це зворотні лапки не регулярні лапок (під тильдой ~ на клавіатурі).) Це буде відправляти вихід command1
в command2
якості аргументів командного рядка. Зауважте, що імена файлів, що містять пробіли (нові рядки тощо), будуть розбиті на окремі аргументи.
find
дозволяють писати:, find . -name '*.foo' -exec cat {} +
де +
вказано, що find
слід групувати стільки імен файлів, скільки зручно, в одне виклик команди. Це дуже корисно (воно стосується пробілів тощо у назвах файлів, не вдаючись до -print0
та xargs -0
).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008 додав +
маркер, find
що означає, що він тепер автоматично групує стільки файлів, скільки розумних, в одне виконання команди, як xargs
і у нас, але має ряд переваг:
Проблема з іменем файлу - це проблема, яка xargs
не має -0
можливості, і проблема "запустити навіть з нульовими іменами файлів" є проблемою з -0
варіантом або без нього, але GNU xargs
має -r
або --no-run-if-empty
можливість запобігти цьому. Крім того, це позначення скорочує кількість процесів, а не те, що ви, ймовірно, вимірюєте різницю в продуктивності. Отже, ви могли б розумно написати:
find . -exec grep something {} +
find . -print | xargs grep something
Якщо ви працюєте в Linux або маєте команду GNU find
та xargs
команди, тоді використовуйте за -print0
допомогою find
і -0
з xargs
для обробки імен файлів, що містять пробіли та інші символи непарних кульок.
find . -print0 | xargs -0 grep something
grep
Якщо ви не хочете, щоб імена файлів (лише текст), тоді додайте відповідний параметр grep
(як правило, -h
для придушення "заголовків"). Щоб абсолютно гарантувати, що ім'я файлу друкується grep
(навіть якщо знайдено лише один файл, або останній виклик grep
має лише 1 ім’я файлу), тоді додайте /dev/null
до xargs
командного рядка, щоб завжди було принаймні два імені файлів.
xargs grep something
.
find
прокладаються на стандартний вхід xargs
. xargs
Програма зчитує стандартний ввід, розділяючи вхід в порожній простір (прогалини, нові рядки, вкладки і т.д.) і додає число слів в команду grep something
і виконує командний рядок. xargs
потім продовжує зчитування введення та виконання команд, поки не закінчиться введення. xargs
запускає grep
команду стільки разів, скільки потрібно для введення, яке їй дано (з find
цього прикладу).
/dev/null
втратити повідомлення про помилки.
Існує декілька способів передати список команд, повернених find
командою, cat
команді, хоча технічно не всі використовують трубопроводи, і жоден насправді не передає безпосередньо cat
.
Найпростішим є використання зворотних посилань ( `
):
cat `find [whatever]`
Це приймає результат find
і ефективно розміщує його в командному рядку cat
. Це не працює добре, якщо find
має занадто багато вихідних даних (більше, ніж вміщається в командному рядку) або якщо у виводу є спеціальні символи (наприклад, пробіли).
У деяких оболонках, в тому числі bash
, можна використовувати $()
замість задньої панелі:
cat $(find [whatever])
Це менш портативно, але нестабільно. Крім цього, він має майже ті самі застереження, що і бекстейки.
Оскільки виконання інших команд над тим, що було знайдено, є загальним для використання find
, функція find має -exec
дію, яка виконує команду для кожного знайденого файла:
find [whatever] -exec cat {} \;
Це {}
заповнювач імені файлу і \;
позначає кінець команди (Можливо, після цього можна виконати інші дії -exec
.)
Це запускається cat
один раз для кожного окремого файлу, а не запускає один екземпляр cat
передачі йому декількох імен файлів, що може бути неефективним і не може мати поведінку, яку ви хочете для деяких команд (хоча це добре для cat
). Синтаксис також незручний для набору - вам потрібно уникнути крапки з комою, оскільки крапка з комою є особливою для оболонки!
Деякі версії find
( в першу чергу в версії GNU) дозволяють замінити ;
з +
для використання -exec
« в режимі S дописування для запуску менше випадків cat
:
find [whatever] -exec cat {} +
Це передасть кілька імен файлів до кожного виклику cat
, що може бути більш ефективним.
Зауважте, що для цього не гарантується використання одного виклику. Якщо командний рядок буде занадто довгим, аргументи поширюються на кілька викликів cat
. Бо cat
це, мабуть, не велика справа, але для деяких інших команд це може змінити поведінку небажаними способами. У системах Linux обмеження довжини командного рядка досить велике, тому поділ на кілька викликів є досить рідкісним порівняно з деякими іншими ОС.
Класичним / портативним підходом є використання xargs
:
find [whatever] | xargs cat
xargs
запускає вказану команду ( cat
у цьому випадку) та додає аргументи на основі того, що вона читає з stdin. Так само, як і -exec
з +
цим, це порушить командний рядок, якщо це необхідно. Тобто, якщо find
виробляється занадто багато результату, він запускатиметься cat
кілька разів. Як було сказано в розділі про -exec
раніше, є деякі команди, де це розщеплення може спричинити різну поведінку. Зауважте, що при такому використанні xargs
виникають проблеми з пробілами у назви файлів, оскільки xargs
просто використовується пробіл як роздільник.
Найбільш надійний, портативний та ефективний метод також використовує xargs
:
find [whatever] -print0 | xargs -0 cat
-print0
Прапор вказує find
використовувати \0
(нульовий символ) роздільники між іменами файлів і -0
прапор вказує xargs
очікувати ці \0
роздільники. Ця поведінка має майже однакову поведінку з -exec
... +
підходом, хоча і більш портативною (але, на жаль, більш багатослівною).
ls
.
$()
Також працює з іншими командами find
.
Мені звучить робота для сценарію оболонки:
for file in 'find -name *.xml'
do
grep 'hello' file
done
чи щось подібне
У команді find є аргумент -exec, який ви можете використовувати для таких речей, ви можете просто зробити grep безпосередньо, використовуючи це.
Наприклад ( звідси й інші хороші приклади на цій сторінці ):
find . -exec grep "www.athabasca" '{}' \; -print
В bash, було б доречним наступне:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Тут ви знайдете всі файли в /dir
каталозі та безпечно вкажіть назви файлів у файли, в xargs
які безпечно працюватимуть grep
.
Пропуск xargs
не є хорошою ідеєю, якщо у вас багато тисяч файлів /dir
; cat
зламається через надмірну довжину списку аргументів. xargs
розберемо це все для вас.
-print0
Аргумент find
сіток з -0
аргументом xargs
для обробки імен файлів з пробілами правильно. -i
Аргумент xargs
дозволяє вставити ім'я файлу , де це необхідно в cat
командному рядку. Дужки замінюються назвою файлу, переданого в cat
команду з find
.
Це працює для мене
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Це надрукує ім'я та вміст файлів лише рекурсивно.
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Редагувати (вдосконалена версія): Це надрукує назву та вміст текстових файлів (ascii) лише рекурсивно.
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
Ще одна спроба
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
Ви намагаєтесь знайти текст у файлах? Ви можете просто використовувати grep для цього ...
grep searchterm *
Список та перегляд вмісту всіх файлів abc.def на сервері в каталогах / ghi та / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
Щоб перелічити abc.def файли, котрі коментують записи та відображають, див. Ці записи в каталогах / ghi та / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
find -name '*.foo' -print
працював для мене чудово ... Спасибі