이런 기능을 사용하고 있습니다.
$ find-grep () { find . -type f -name "$1" -print0 | xargs -0 grep "$2" ; }
입력한 후:
$ find-grep *.c foo
마지막 명령 문자열을 확장하고 싶습니다. 이 경우:
find . -type f -name "*.c" -print0 | xargs -0 grep "foo"
쉽게 할 수 있는 방법이 있나요?
답변1
@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"
}
답변2
한 가지 방법은 다음과 같습니다.
$ 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개의 파일에 "foo"라는 문자열이 포함된 함수의 실제 실행입니다.
$ 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 ...
.