Псевдонім є внутрішнім для оболонки, де він визначений. Це не видно для інших процесів. Те саме стосується функцій оболонки. xargs
це окрема програма, яка не є оболонкою, тому не має поняття псевдонімів або функцій.
Ви можете змусити xargs викликати оболонку, а не викликати grep
безпосередньо. Однак лише виклик оболонки недостатньо, ви також повинні визначити псевдонім у цій оболонці. Якщо псевдонім визначений у вашому .bashrc
, ви можете джерело цього файлу; однак це може не спрацювати, якщо .bashrc
виконуються інші завдання, які не мають сенсу в неінтерактивній оболонці.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
Остерігайтеся тонкощів вкладеного цитування під час введення повторного тексту. Ви можете спростити своє життя, передавши регулярний параметр як параметр оболонці.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
Ви можете виконати пошук псевдоніму явно. Тоді xargs
побачимо grep -n --color=always
.
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
В zsh:
find . -name '*.py' | xargs $aliases[grep] regex_here
До речі, зауважте, що find … | xargs …
перерви на імена файлів, що містять пробіли (серед інших) . Ви можете виправити це, змінивши на нульові записи:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
або використовуючи -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
Замість того, щоб дзвонити find
, ви можете робити все цілком всередині оболонки. Глобальний шаблон реверсивно **/
переміщує каталоги. У bash, вам потрібно запустити, shopt -s globstar
щоб спочатку ввімкнути цей шаблон.
grep regex_here **/*.py
Це має кілька обмежень:
- Якщо багато файлів збігаються (або якщо вони мають довгі шляхи), команда може вийти з ладу, оскільки вона перевищує максимальну довжину командного рядка.
- У bash ≤4.2 (але не в останніх версіях, ні в ksh чи zsh)
**/
повторюється переклад у символічні посилання на каталоги.
Інший підхід полягає у використанні процесу заміщення, як це запропонував MariusMatutiae .
grep regex_here <(find . -name '*.py')
Це корисно, коли **/
це не застосовується: для складних find
виразів або в bash ≤4.2, коли ви не хочете повторюватися за символічними посиланнями. Зауважте, що це перерва на імена файлів, що містять пробіли; вирішення завдання полягає у встановленні IFS
та відключенні глобалізації , але воно починає трохи складніше:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )