내 .bash_aliases에서는 다음과 같이 명령줄에서 사용할 함수를 정의합니다.
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
이 함수는 결과를 다른 grep 명령으로 파이프하는 grep 명령을 작성합니다(불행히도 이전 버전을 사용하고 있기 때문에 이것은 복잡합니다).
search() {
local file_names opt OPTARG OPTIND pattern
file_names=()
while getopts ":n:" opt; do
case $opt in
n)
file_names+=( "$OPTARG" )
;;
esac
done
shift $((OPTIND-1))
pattern="$1"
shift
if (( ${#file_names[@]} > 0 )); then
file_names="${file_names[@]}"
file_names=${file_names// /':\|'}:
grep -I -r "$pattern" "$@" | grep "$file_names"
else
grep -I -r "$pattern" "$@"
fi
}
이 함수를 호출하기 위해 다른 함수를 정의했습니다.
search-some-set-of-files() {
local file_names directories
file_names=( "-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml" )
directories=( "/c/code/website/" "/c/stuff/something/whatever/" )
search "${file_names[@]}" "$@" "${directories[@]}"
}
명령줄에서 다음과 같이 함수를 호출합니다.
search-some-set-of-files SomeTextIWantToSearchFor
어떤 이유로 결과에는 다음이 포함됩니다.파일당대상 디렉토리에. 즉, 내가 지정한 파일 이름을 기준으로 grep으로 결과가 필터링되지 않습니다.
search-some-set-of-files
명령을 에코하도록 함수의 마지막 줄을 변경하면 다음과 같은 결과를 얻습니다.
$ search-some-set-of-files SomeTextIWantToSearchFor
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
이것이 바로 내가 원하는 것입니다. 이 명령을 명령줄에 복사(또는 그대로 입력)하면 결과는 원래대로입니다.
디버그 모드( )를 활성화하면 set -x
각 인수를 개별적으로 인용하는 쉘을 볼 수 있습니다.
$ search-some-set-of-files SomeTextIWantToSearchFor
+ search-some-set-of-files SomeTextIWantToSearchFor
+ local file_names directories
+ file_names=("-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml")
+ directories=("/c/code/website/" "/c/stuff/something/whatever/")
+ search '-n page1.cshtml' '-n page2.cshtml' '-n page3.cshtml' SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
+ return
+ etc...
그래서 문제는 매개변수를 함수에 전달하는 방법이라고 생각합니다 search
. 어떻게 해결할 수 있나요?
답변1
귀하의 질문은 두 번째 질문입니다 grep
.
... | grep "$file_names"
-n
함수를 호출하면 와 파일 이름 사이의 공백( )이 배열 -n page1.cshtml
에 포함됩니다 . $file_names
그런 다음 다음을 교체하십시오.
file_names=${file_names// /':\|'}:
:\|
선행 공백으로 인해 문자열 시작 부분에 추가 내용이 추가됩니다. 따라서 두 번째 grep
명령은 실제로 다음과 같습니다.
... | grep ":\|page1.cshtml:\|page2.cshtml:\|page3.cshtml:"
결과, grep
경기모두모든 결과 행은 행을 포함 filename:
하고 일치하기 때문입니다 :
.
따라서 간단한 해결책은 공백을 제거하는 것입니다.
file_names=( "-npage1.cshtml" "-npage2.cshtml" "-npage3.cshtml" )
그러면 모든 것이 예상대로 작동할 것입니다.