Как я могу использовать команды aliased с 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
, поэтому, пожалуйста, укажите, является ли ответ специфичным для оболочки.
Ответы
Ответ 1
Псевдонимы специфичны для оболочки - в этом случае, скорее всего, 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
Он работал для моего основного тестирования.
Ответ 2
Поверните "gi" в script вместо
например, в /home/$USER/bin/gi
:
#!/bin/sh
exec /bin/grep -i "[email protected]"
не забывайте отмечать исполняемый файл.
Ответ 3
Предложение здесь заключается в том, чтобы избежать xargs и использовать цикл while while read вместо xargs:
find -name \*bar\* | while read file; do gi foo "$file"; done
См. принятый ответ в приведенной выше ссылке для уточнений, связанных с пробелами или символами новой строки в именах файлов.
Ответ 4
Это безопасно для специальных символов:
find . -print0 | xargs -0 bash -ic 'echo gi foo "[email protected]"' --
-print0
и -0
используют \0
или NUL
-терминированные строки, поэтому вы не получаете странных вещей, когда имена файлов имеют в них пробелы.
bash
устанавливает первый аргумент после командной строки как $0
, поэтому мы передаем ему фиктивный аргумент (--
), так что первый файл, указанный в find
, не потребляется $0
.
Ответ 5
Для tcsh (который не имеет функций) вы можете использовать:
gi foo `find -name "*bar*"`
Для bash/ksh/sh вы можете создать функцию в оболочке.
function foobar
{
gi $1 `find . -type f -name "*"$2"*"`
}
foobar foo bar
Помните, что использование backquotes в оболочке более выгодно, чем использование xargs из нескольких точек зрения. Поместите функцию в свой .bashrc.
Ответ 6
Используя 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
Ответ 7
Самым простым решением в вашем случае будет расширение встроенного псевдонима. Но это справедливо только для csh/tcsh.
find -name \*bar\* | xargs 'alias gi' foo
для bash это будет сложнее, не так удобно, но все же может быть полезно:
find -name \*bar\* | xargs 'alias gi | cut -d "'" -f2' foo