Псевдонім є внутрішнім для оболонки, де він визначений. Це не видно для інших процесів. Те саме стосується функцій оболонки. 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') )