Bash 4.2 на CentOS 6.5:
По моему у ~/.bash_profile
меня есть куча псевдонимов, в том числе:
alias grep='grep -n --color=always'
так что я могу получить цветную подсветку и печатать номера строк автоматически при запуске grep
. Если я запускаю следующее, выделение работает как положено:
$ grep -Re 'regex_here' *.py
Однако, когда я запустил это недавно:
$ find . -name '*.py' | xargs grep -E 'regex_here'
результаты не были выделены, а номера строк не были напечатаны, что заставило меня вернуться назад и явно добавить -n --color=always
в grep
команду.
- Не
xargs
читает псевдонимы в среде? - Если нет, есть ли способ заставить это сделать это?
xargs
команде. Я пытаюсь выяснить, есть ли способ, с помощью которого я могу напрямую назвать свой псевдонимxargs
.export GREP_OPTIONS='-n --color=always'
перед командой xargs?.bash_profile
. Не стесняйтесь написать ответ ...Ответы:
Псевдоним является внутренним для оболочки, где он определен. Это не видно другим процессам. То же самое касается функций оболочки.
xargs
это отдельное приложение, которое не является оболочкой, поэтому не имеет понятия псевдонимов или функций.Вы можете заставить xargs вызывать оболочку вместо
grep
прямой. Однако простого вызова оболочки недостаточно, вы также должны определить псевдоним в этой оболочке. Если псевдоним определен в вашем.bashrc
, вы можете получить этот файл; однако это может не сработать, вы.bashrc
выполняете другие задачи, которые не имеют смысла в неинтерактивной оболочке.Остерегайтесь тонкостей вложенного цитирования при вводе регулярного выражения. Вы можете упростить свою жизнь, передав регулярное выражение в качестве параметра в оболочку.
Вы можете явно выполнить поиск псевдонима. Тогда
xargs
увидимgrep -n --color=always
.В зш:
Кстати, обратите внимание, что
find … | xargs …
разрывы на имена файлов, содержащие пробелы (среди других) . Вы можете исправить это, перейдя к записям с нулевым разделением:или с помощью
-exec
:Вместо вызова
find
вы можете делать все целиком внутри оболочки. Шаблон**/
глобуса рекурсивно пересекает каталоги. В bash вам нужноshopt -s globstar
сначала запустить этот шаблон глобуса.Это имеет несколько ограничений:
**/
рекурсивные ссылки на каталоги.Другой подход заключается в использовании процесса замены, как это предложено MariusMatutiae .
Это полезно, когда
**/
не применимо: для сложныхfind
выражений или в bash ≤4.2, когда вы не хотите использовать рекурсивные ссылки. Обратите внимание, что это нарушает имена файлов, содержащие пробелы; Обходной путь должен установитьIFS
и отключить глобализацию , но он начинает становиться немного сложным:источник
использование
alias xargs='xargs '
источник
sudo
…Пожалуйста, примите это как демонстрацию другого подхода, который я не могу найти в соответствующем вопросе SO :
Вы можете написать функцию-обертку, для
xargs
которой проверяется, является ли первый аргумент псевдонимом, и если это так, разверните ее соответствующим образом.Вот код, который делает именно это, но, к сожалению, требует оболочки Z и, следовательно, не запускает 1: 1 с bash (и, честно говоря, я не привык к bash достаточно для его портирования):
Доказательство того, что это работает:
источник
Более простое и элегантное решение - использовать процесс подстановки :
Он не создает новую оболочку, как конвейер, что означает, что вы все еще находитесь в своей исходной оболочке, в которой определен псевдоним, и результат будет именно таким, каким вы хотите его видеть.
Просто будьте осторожны, не оставляйте пробела между перенаправлением и круглыми скобками, иначе bash выдаст ошибку. Насколько я знаю, процесс замены поддерживается Bash, Zsh, Ksh {88,93}, но не pdksh (мне сказали, что это должно быть еще не ).
источник
find
команд, хотя вам нужно помнить, что он будет разбит на пробелы, и это не может быть исправлено так легко, какfind | xargs
может быть (путем переключения на-print0
и-0
или с помощью-exec
). Когда это применимо,**/
это проще и надежнее.grep будет читать набор параметров по умолчанию из переменной среды GREP_OPTIONS. Если вы положите
в вашем .bashrc переменная будет передана в подоболочки, и вы получите ожидаемые результаты.
источник
--line-number
или--color=always
в ,GREP_OPTIONS
если это не только для одной команды, это нарушит много сценариев.--color=auto
это нормально иметь там, и это все. Поместив эту строку в ваш,.bashrc
вы сломаете много вещей./etc/init.d/cron
моей системы:value=`egrep "^${var}=" "$ENV_FILE" | tail -n1 | cut -d= -f2`
. Или из/usr/bin/pdfjam
:pdftitl=`printf "%s" "$PDFinfo" | grep -e … | sed -e …`
. Псевдоним не является проблемой, так как он не виден в сценариях.GREP_OPTIONS
очень сильно нарушает предсказуемость, за исключением нескольких опций типа--color=auto
(для которых она и была разработана).