찾기 명령 후 커넥터 사용


10

find 명령을 사용하여 무언가를 찾은 경우에만 bash에서 'found'를 인쇄하고 싶습니다. 그러나 &&를 사용하면 도움이되지 않습니다. 아무것도 찾지 않아도 '발견'인쇄됩니다. 예:

$ pwd
/data/data/com.termux/files/home/test/test1/test4
$ ls
xaa  xab
$ find . -name xac && echo 'found'
found
$ find . -name xaa && echo 'found'
./xaa
found

답변:


18

find스스로 인쇄 할 수 있습니다 found:

find . -name xac -printf "found\n" -quit

-quitfind 첫 경기 후 종료 때문에, found한 번만 대부분에 인쇄됩니다.

유닉스 및 리눅스의 비슷한 스레드에서 ( 아무 것도 발견되지 않으면 찾기 실패 ) 아무것도 발견하지 grep -qz않으면 0이 아닌 종료 상태를 반환했습니다 find.

find /some/path -print0 -quit | grep -qz .

어떤 당신이 사용하는 복합 명령을 구성하는 데 사용할 수있는 &&또는 if:

find /some/path -print0 -quit | grep -qz . && echo found

나는 이것을 잠시 쳐다 봐야했다. /some/path어디에서 찾아야할지 찾아 내지 만 찾을 곳은 없습니다. 링크 된 답변에서 동일합니다. 나를 위해 일하는 것은입니다 find /some/path -name xac -print0 -quit | grep -qz . && echo found. 내가 뭘 놓 쳤니?
Joe

@Joe 여기서 중요한 것은입니다 -print0 -quit. 당신이 그 앞에 두는 것은 당신이 찾고 싶은 것에 달려 있습니다. 나는 여기서 그것을 생략하기로 결정했다.
muru

13

muru의 답변 은 적절하며 파일이 발견되면 인쇄하려는 경우에 적합합니다. 일반적인 경우와 같은 외부 명령을 실행하려는 경우 플래그를 echo사용할 수 있습니다 -exec.

$ find . -name 'xac' -exec echo "I found " {} \; -quit             
I found  ./xac

{}부분은 파일 이름을 인수 사이 -exec\;인수로 명령에 전달합니다. 참고 \이전 ;- 그것을 방지 그것을 잘못 해석 쉘; 세미콜론 의미 명령의 끝,하지만 슬래시로 탈출 할 때, 쉘에 전달 될 literall 텍스트로 취급됩니다 쉘 폐쇄에 find명령하고 닫는 역할을 명령 찾을 -exec플래그의 인수를.


if found do this; else do that정렬 조건을 구성하기 위해 명령 종속 $()test명령 (aka [) 을 사용할 수 있습니다 .

$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"                                                                                              
not found

$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"                                                                                                  
found

Dan의 의견 해결

의견에 Dan은 물었다 :

"I found {}"를 echo "I found"{}보다 낫지 않습니까? echo의 경우에는 문제가 없지만 누군가 명령을 복사하고 echo를 다른 명령으로 바꾸면 문제가있을 수 있습니다.

먼저 문제를 이해합시다. 일반적으로 쉘에는 단어 분리 개념이 있는데, 이는 인용되지 않은 변수와 위치 매개 변수가 확장되어 별도의 항목으로 취급됨을 의미합니다. 예를 들어,이 변수가있는 경우 var와 포함 된 hello world텍스트를 당신이 할 때, touch $var쉘은 두 개의 별도 항목으로 무너 뜨리는 것 hello하고 world그리고 touch당신이 개 별도의 파일을 만들려고하는 것처럼 그것을 이해한다; 그렇게하면 touch "$var"쉘은 hello world하나의 단위로 취급 하고 touch하나의 파일 만 생성합니다. 이것은 쉘이 작동하는 방식으로 만 발생한다는 것을 이해하는 것이 중요합니다.

대조적으로 find명령은 find자체적 으로 처리 되고 execvp()시스템 호출에 의해 실행 되므로 쉘이 없기 때문에 이러한 동작이 발생하지 않습니다 . 중괄호는 쉘에서 특별한 의미를 갖지만, find처음에는 아니라 명령 의 중간에 나타나기 때문에이 경우 쉘에 특별한 의미가 없습니다. 다음은 예입니다. 어려운 파일 이름을 몇 개 만들어서 stat명령의 인수로 전달해 봅시다 .

$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt

$ find -type f -exec stat -c "%F" {} \; -print                                                                                                                         
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt

보시다시피 stat어려운 파일 이름을 완벽하게 받아들입니다 find. 이는 휴대용 스크립트에서 사용하는 것이 권장되는 주된 이유 중 하나이며 디렉토리 트리를 통과하고 잠재적으로 파일 이름이있는 파일 이름으로 무언가를 수행하려는 경우 특히 유용합니다 그들 안에 특수 문자. 따라서에서 실행되는 명령에 대해서는 중괄호를 인용 할 필요가 없습니다 find.

쉘이 관여 할 때 다른 이야기입니다. 때로는 파일 이름을 처리하기 위해 셸을 사용해야합니다. 이 경우 인용은 실제로 중요하지만 그것이 문제가 아니라는 것을 인식하는 것이 중요합니다. 단어를 나누는 것은 쉘입니다.

$ find -type f -exec bash -c "stat {}" sh \;   
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory

그래서 우리가 shell 내에서 인용 하면 작동합니다. 그러나 다시, 그것은 쉘이 아니라 중요합니다 find.

$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;                                                                                                                 
regular empty file
regular empty file
regular empty file

하지 않을까요 echo "I found {}"보다 더 나은 echo "I found " {}? echo의 경우에는 문제가 없지만 누군가 명령을 복사하여 echo를 다른 명령으로 바꾸면 문제가있을 수 있습니다.
Dan

@Dan 주제가 너무 길어서 댓글에 토론하지 않았으므로 답변을 수정했습니다. 참조하십시오
Sergiy Kolodyazhnyy

1
세미콜론이 필요한 이유를 마침내 이해하게 해주셔서 감사합니다. 또한 인용에 대한 훌륭한 설명.
Joe

1
내 의견에 대한 답변으로 많은 세부 사항을 기대하지 않았습니다. 나는 그 설명을 대단히 감사합니다, 감사합니다!
Dan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.