.bashrc
내 파일 에 다음 bash 함수를 정의하려고 합니다 .
function myfind() {
find $1 -not -path venv -not -path .tox -name "$2" | xargs grep -n "$3"
}
이것은 내 기대에 미치지 못했습니다. 이 기능을 사용하여 파일에서 텍스트를 검색할 때, 예를 들어
myfind . *.py test
아무것도 반환하지 않습니다. 하지만 표현을 직접 사용할 때 즉
find . -not -path venv -not -path .tox -name "*.py" | xargs grep -n "test"
일부 일치 항목을 반환합니다.
나는 다음과 같은 큰 따옴표를 사용해 보았습니다.
function myfind() {
find $1 -not -path venv -not -path .tox -name '"$2"' | xargs grep -n '"$3"'
}
또는
function myfind() {
find $1 -not -path venv -not -path .tox -name "'$2'" | xargs grep -n "'$3'"
}
이런 따옴표를 피하려고 노력하십시오
function myfind() {
find $1 -not -path venv -not -path .tox -name \"$2\" | xargs grep -n \"$3\"
}
그러나 이들 중 어느 것도 작동하지 않는 것 같습니다.
이 bash 함수가 매개변수 주위에 따옴표를 "사용"하도록 수정하려면 어떻게 해야 합니까?
답변1
티팀:
myfind() {
find "$1" '(' -name venv -o -name .tox ')' -prune -o \
-name "$2" -type f -exec grep -Hne "$3" -- {} +
}
그런 다음:
myfind . '*.py' test
당신은 또한 볼 수 있습니다찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?그러한 출력을 호출하는 것이 왜 xargs
잘못된 것입니까?find
귀하의 접근 방식에는 몇 가지 다른 문제가 있습니다.
-path venv
-path
고려 중인 파일의 전체 경로와 일치하는 항목 은 없으며 호출의 최상위 수준에서만 일치합니다<contents-of-$1>/subdir/file
.myfind venv ...
나는 당신이 이라는 디렉토리에 저장된 파일을 무시하고 싶다고 가정합니다venv
. 이렇게 할 수는 있지만! -path '*/venv/*'
나중에 디렉터리에 있는 모든 파일을 필터링하는 것보다 처음부터 해당 디렉터리에 들어가지 않도록 지시하는 것이 더 효율적입니다. (파일 경로가 로케일에서 유효한 텍스트가 아닌 경우에도 문제가 발생할 수 있습니다.) .find
! -path '*/venv/*'
for , 당신은 의 두 번째에서 두 번째 인수를 형성하기 위해 현재 디렉토리에서 일치하는 파일 목록으로
myfind first *.py last
확장하도록 쉘에 요청하고 있습니다. 이는 for 에 전달하여 after 에 전달 하려는 리터럴 인수 입니다 . 따라서 다음이 필요합니다. 쉘이 문자를 와일드카드로 해석하지 않도록 문자를 인용하십시오 . 여기서는 나머지 3개 문자( , 및 )가 쉘에 특별하지 않기 때문에 전체 내용을 while 또는 으로 인용하는 것으로 충분합니다 .*.py
myfind
*.py
myfind
myfind
find
-name
*
*.py
'*.py'
'*'.py
\*.py
.
p
y
bash 대신 zsh를 사용하는 경우 .NET
alias myfind='noglob myfind'
에서 이를 수행할 수 있습니다. 그러면 쉘 없이 확장myfind
할 수 있습니다 .myfind . *.py test
*.py
"$1"
분할+glob( , 아님 ) 을 방지하려면 매개변수 확장을 인용해야 합니다$1
.-H
GNU 확장자 가 없으면find
파일이 하나만 발견 되면grep
해당 경로가 인쇄되지 않으므로 일치하는 위치를 알 수 없습니다.grep
지원되지 않는 구현 의 경우 추가 인수로 전달할-H
수 있습니다 ./dev/null
-exec grep -ne "$3" -- /dev/null {} +
!
non-standard 에 해당하는 표준(및 더 짧은) 항목을 참조하세요-not
.with 로 시작
grep -n "$3"
하면 옵션으로 처리됩니다 . 따라서 옵션 에 인수로 내용을 전달하십시오. 동일한 문제가 존재 하지만 안타깝게도 표준 솔루션은 없습니다. 차단된 콘텐츠 가 고려됩니다.$3
-
grep
-e "$3"
$3
-e
find "$1"
find -- "$1"
$1
옵션find
그것 으로 시작-
하지만 여전히 다음과 같이 처리됩니다.술부, 그러니까 말이 안 돼요. 예를 들어,!
또는이라는 디렉터리(
도 문제가 될 수 있습니다. BSD는find
이를 지원하지만 GNU와 대부분의 다른 구현은 그렇지 않습니다. 대시로 시작하는 디렉터리를 전달하는 데 사용됩니다.find -f "$1"
find
find
myfind ./-dir-starting-with-data- '*.py' pattern
sh
코드에서 유일한 비표준 구문은function name()
함수 정의 구문입니다. ksh 구문은function name {...;}
, Bourne 이고 표준bash
구문은 입니다name() {...;}
.bash
가끔 지원 되기도 하지만function name() { ...; }
이를 사용해야 할 실질적인 이유는 없습니다.-type f
고려사항만 추가했습니다정기적인장치 파일이나 fifo 내에서 검색을 시작 하고 싶지 않을 것이고grep
디렉터리나 소켓에 대한 오류가 보고될 것이기 때문입니다. GNU를 사용하면find
이를 로 대체하여-xtype f
최종적으로 일반 파일로 확인되는 심볼릭 링크도 고려할 수 있습니다.