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