Как я могу использовать псевдонимы команд с xargs?

У меня есть следующий псевдоним в моих .aliases:

alias gi grep -i

и я хочу искать foo без учета регистра во всех файлах, в имени которых есть строка bar:

find -name \*bar\* | xargs gi foo

Вот что я получаю:

xargs: gi: No such file or directory

Есть ли способ использовать псевдонимы в xargs, или мне нужно использовать полную версию:

   find -name \*bar\* | xargs grep -i foo

Примечание. Это простой пример. Кроме gi у меня есть несколько довольно сложных псевдонимов, которые я не могу так легко расширить вручную.

Изменить: я использовал tcsh, поэтому укажите, относится ли ответ к конкретной оболочке.


person Nathan Fellman    schedule 11.06.2009    source источник
comment
Вот похожий (хотя и не идентичный) вопрос: stackoverflow.com /вопросы/513611/   -  person Nathan Fellman    schedule 08.03.2010


Ответы (8)


Псевдонимы специфичны для оболочки - в данном случае, скорее всего, для bash. Чтобы выполнить псевдоним, вам нужно выполнить bash, но псевдонимы загружаются только для интерактивных оболочек (точнее, .bashrc будет читаться только для интерактивной оболочки).

bash -i запускает интерактивную оболочку (и исходный файл .bashrc). bash -c cmd запускает cmd.

Соедините их вместе: bash -ic cmd запускает cmd в интерактивной оболочке, где cmd может быть функцией bash. / псевдоним, определенный в вашем файле .bashrc.

find -name \*bar\* | xargs bash -ic gi foo

должен делать то, что вы хотите.

Изменить: я вижу, что вы пометили вопрос как «tcsh», поэтому решение, специфичное для bash, неприменимо. С tcsh вам не нужен -i, так как он выглядит как .tcshrc, если вы не укажете -f.

Попробуй это:

find -name \*bar\* | xargs tcsh -c gi foo

Это сработало для моего базового тестирования.

person camh    schedule 11.06.2009
comment
См. этот ответ, если вы хотите корректно работать с файлами, включая пробелы. - person Tom Hale; 01.12.2016

Вместо этого превратите «gi» в сценарий

eg, in /home/$USER/bin/gi:

#!/bin/sh
exec /bin/grep -i "$@"

не забудьте отметить исполняемый файл.

person Peter Ericson    schedule 11.06.2009

Предложение здесь состоит в том, чтобы избегать xargs и использовать цикл "пока читается" вместо xargs :

find -name \*bar\* | while read file; do gi foo "$file"; done

См. принятый ответ по ссылке выше, чтобы узнать об уточнениях, касающихся пробелов или новых строк в именах файлов.

person Pete TerMaat    schedule 11.06.2009
comment
Если в именах файлов есть пробелы или новые строки, это не так хорошо, как xargs с параметром -0 (и поиск с -print0). - person Jonathan Leffler; 11.06.2009


Это безопасно для специальных символов:

find . -print0 | xargs -0 bash -ic 'gi foo "$@"' --

-print0 и -0 используют строки, заканчивающиеся \0 или NUL, чтобы не происходило странных вещей, когда в именах файлов есть пробелы.

bash устанавливает первый аргумент после командной строки как $0, поэтому мы передаем ему фиктивный аргумент (--), чтобы первый файл, указанный find, не использовался $0.

person Tom Hale    schedule 01.12.2016

Для tcsh (у которого нет функций) вы можете использовать:

gi foo `find -name "*bar*"`

Для bash/ksh/sh вы можете создать функцию в оболочке.

   function foobar 
   {
      gi $1 `find . -type f -name "*"$2"*"`
   }

   foobar foo bar

Помните, что использование обратных кавычек в оболочке более выгодно, чем использование xargs с разных точек зрения. Поместите функцию в свой .bashrc.

person Ryan Oberoi    schedule 11.06.2009

Используя Bash, вы также можете указать количество аргументов, передаваемых вашему псевдониму (или функции), например:

alias myFuncOrAlias='echo'  # alias defined in your ~/.bashrc, ~/.profile, ...
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0

(должно работать для tcsh аналогичным образом)

# alias definition in ~/.tcshrc
echo arg1 arg2 | xargs -n 1 tcsh -cim 'myFuncOrAlias "$1"' arg0  # untested
person tilo    schedule 19.07.2010

Самым простым решением в вашем случае было бы расширение вашего псевдонима в строке. Но это справедливо только для csh/tcsh.

find -name \*bar\* | xargs `alias gi` foo

для bash это будет сложнее, не так удобно, но все же может быть полезно:

find -name \*bar\* | xargs `alias gi | cut -d "'" -f2` foo
person Feniks    schedule 27.08.2019