Псевдоним является внутренним для оболочки, где он определен. Это не видно другим процессам. То же самое касается функций оболочки. 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
В зш:
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') )