С ударом (только начиная с версии 4.0) можно сделать это:
shopt -s globstar
wc -l **/*.php
В zsh можно всегда делать wc -l **/*.php
.
Более нормальная версия @slm:
find-grep() {
cmd=(find . -type f -name "$1" -exec grep "$2" {})
printf '%q ' "${cmd[@]}"
printf '+\n'
"${cmd[@]}" +
}
(никакая потребность в каналах или xargs
здесь) Или:
find-grep () (
set -x
find . -type f -name "$1" -exec grep "$2" {} +
)
(отметьте ()
вместо {}
запустить подоболочку для ограничения объема set -x
. Обратите внимание, что это не заставляет больше процессов быть разветвленным, это просто что fork
для процесса, который выполнится find
сделан ранее).
Помните, что необходимо заключить подстановочные символы в кавычки, таким образом, они не расширены оболочкой:
find-grep '*.c' pattern
Если вместо этого, Вы хотите, чтобы это было продвинуто к истории, так, чтобы Вы видели расширенную команду при нажатии клавиши Up Вы могли записать это:
find-grep() {
cmd=$(printf '%q ' find . -type f -name "$1" -exec grep "$2" {})+
history -s "$cmd"
eval "$cmd"
}
Вот один способ сделать это:
$ find-grep () {
cmd=(find . -type f -name \"$1\" -print0 \| xargs -0 grep \"$2\")
printf "%s\n" "${cmd[*]}"
eval "${cmd[*]}"
}
Вот некоторые демонстрационные данные.
$ ls -l
total 8
-rw-rw-r-- 1 saml saml 4 Sep 21 10:44 1.c
-rw-rw-r-- 1 saml saml 4 Sep 21 10:44 2.c
-rw-rw-r-- 1 saml saml 0 Sep 21 10:22 3.c
-rw-rw-r-- 1 saml saml 0 Sep 21 10:22 4.c
-rw-rw-r-- 1 saml saml 0 Sep 21 10:22 5.c
Вот наша функция в действии, 2 из файлов содержат строку "нечто".
$ find-grep '*.c' "foo"
find . -type f -name "*.c" -print0 | xargs -0 grep "foo"
./2.c:foo
./1.c:foo
Эта конкретная версия Вашей функции делает следующие вещи по-другому.
$cmd=(find....)
. Команда перенесена в массив, (..)
.$cmd
использование printf
. Мы передаем элементы массива с помощью *
нотация, ${cmd[*]}
, так, чтобы мы получили массив как единственную строку, а не как дискретный список элементов.$cmd
, который выполняет его.Вы могли также перенести функцию как это: set -x ...function... set +x
, который имеет эффект включения отладки только на время ...function...
, и затем выключение его.
$ find-grep () {
set -x
find . -type f -name "$1" -print0 | xargs -0 grep "$2"
set +x
}
$ find-grep *.c foo
+ find . -type f -name '*.c' -print0
+ xargs -0 grep foo
+ set +x
Этот подход не столь легко считать, но он показывает Вам те же грубые функции, просто разбитые на основе того, как они выполнялись. Сначала find ...
, сопровождаемый xargs ...
.
find-grep *.c foo
к исходной команде, если функция не определяется как это?
– ironsand
21.09.2013, 05:58
*.c
)) и regexps. спасибо
– Stéphane Chazelas
21.09.2013, 11:38
eval
. Однако Вам нужно, должен выйти из всех специальных символов в 1$ и 2$ (и необходимо заключить переменные в кавычки как всегда). Помещение двойных кавычек вокруг них работа привычки. Если $1
'*"*'
например, или 2$ '
', that won't be enough. Hence the
printf %q' в решении я дал.
– Stéphane Chazelas
21.09.2013, 20:07
+
быть включенными в присваивание массива? – slm♦ 21.09.2013, 15:39$"..."
для локализации, она не имеет смысла в этом контексте. Вам нужны массивы для отслеживания то, что аргументы или заключение в кавычки использования.+
не включен для предотвращения конечного пробела. – Stéphane Chazelas 21.09.2013, 15:47