grep이 true / false를 반환하거나 다른 방법이 있습니까?


130

이 스크립트의 일부로, 주어진 첫 번째 인수가 파일의 첫 단어와 일치하는지 확인할 수 있어야합니다. 그렇다면 오류 메시지와 함께 종료하십시오. 그렇지 않은 경우 파일에 인수를 추가하십시오. if문장 을 작성하는 방법을 이해 하지만 grep스크립트 내 에서 사용하는 방법을 이해 하지 못합니다 . 나는 grep이런 식으로 보일 것입니다 이해

grep ^$1 schemas.txt

나는 이것이 내가 만드는 것보다 훨씬 쉬워야한다고 생각합니다.

if명령문 에 "너무 많은 인수"오류가 표시 됩니다. 나는 사이의 공백을 제거 grep -q하고 오류 이진 연산자가 예상되었습니다.

if [ grep -q ^$1 schemas.txt ]
then
        echo "Schema already exists. Please try again"
        exit 1
else
        echo "$@" >> schemas.txt
fi

1
[... ]그리고 그것은 작동합니다. 패턴을 인용하고 싶을 수도 있지만 :if grep -q "^$1" schemas.txt; then …
derobert

: 배쉬의 "그룹 명령"기능을 사용하여 한 줄 솔루션 stackoverflow.com/questions/6550484/...
트레버 보이드 스미스

답변:


186

grep0이 아닌 것을 발견 한 경우와 0이 아닌 것을 발견 한 경우 다른 종료 코드를 반환합니다. 에서 if문 제로 (0) 종료 코드가 "true"로하고, 0이 아닌 종료 코드가 false에 매핑에 매핑됩니다. 또한 grep에는 -q일치하는 텍스트를 출력하지 않는 인수가 있지만 종료 상태 코드 만 반환합니다.

따라서 다음과 같이 grep을 사용할 수 있습니다.

if grep -q PATTERN file.txt; then
    echo found
else
    echo not found
fi

간단히 말하면,와 같은 작업을 수행 하면 grep과 마찬가지로 실제로 실행중인 명령 if [ -z "$var" ]…임을 [알 수 있습니다. 내 시스템에서는 /usr/bin/[입니다. (기술적으로 쉘에는 아마도 내장되어 있지만 최적화 된 것입니다. 마치 명령처럼 작동합니다). 동일한 방식으로 작동하며 [true의 경우 0 종료 코드, false의 경우 0이 아닌 종료 코드를 리턴합니다. ( 마무리를 제외하고 test와 동일 )[]


if 문에 대괄호가 필요하지 않은 이유는 무엇입니까? 나는없이 일하고 있지만 왜 그런지 이해하지 못한다. 대괄호 없이도 중첩 할 수 있습니까?
Lauren

@Lauren 빠른 메모를 놓치셨습니까? [if 구문의 일부가 아니며, grep과 같이 (개념적으로) 실행중인 명령입니다.
derobert

2
@Lauren [내부에 grep을 사용하지 말고 어떤 조건을 확인하고 싶은지에 따라 하나를 사용하십시오. (종료 코드를 검사하는 경우 if, btw 내부에서 모든 명령을 사용할 수 있습니다.) ... 글쎄, 아마 grep을 사용할 이유가있을 수 있습니다. [하지만 상당히 복잡한 스크립트 일 것입니다. 정상적인 일이 아닙니다.
derobert

3
참고로, 실행 ls -l /usr/bin/\[man [그보고 [다른 같은 프로그램, 그냥 보이는 통 사적 요소처럼 - 이것은 분명하고 쉽게 이해할 수 있도록해야한다. 편의상 [bash, dash 등의 내장 기능도 있지만 여전히 명령입니다. 또한 type -all [bash에서 시도하십시오 .
cas

1
@AlexanderCska grep이 일치하는 행을 인쇄 (예 : 어딘가에 파이프하기 위해)하려는 경우을 생략하면 -q해당 옵션이 grep을 조용하게합니다 (일치하는 행은 인쇄하지 않음).
derobert

47

또 다른 간단한 방법은을 사용하는 것 grep -c입니다.

패턴과 일치하는 행 수를 출력 (종료 코드로 리턴하지 않음)하므로 일치하지 않으면 0 또는 일치하는 경우 1 이상입니다.

따라서 패턴이 3 회 이상 일치하는지 확인하려면 다음을 수행하십시오.

if [ "$(grep -c "^$1" schemas.txt)" -ge 3 ]; then
  ...

17
보다 정확하게는 한 번만 발견되면 1 을 출력 합니다. 찾은 일치 량에 관계없이 1을 출력하려면 grep -cim1대신 사용하십시오.
manatwork

이 방법을 사용하여 grep error와 grep 'pattern found 0 times'을 구분할 수도 있습니다. (정확한 if 문을 사용하지는 않지만 변수가 필요하다고 생각합니다)
Evan Benn

3

나는 이것에 늦었다는 것을 알고 있지만이 짧은 버전을 좋아합니다.

grep -q ^$1 schemas.txt && echo "Schema already exists. Please try again" || echo "$@" >> schemas.txt

0

파일의 첫 단어를 잡으 -zw려면 grep에 추가해야합니다

if grep -qzw "^$1" file
then 
   ... 
else 
   ... 
fi

없으면 -z우리는 한 줄의 첫 단어를 얻습니다. -w우리가 없으면 부분적인 단어를 얻습니다.


-2

대괄호와 함께 사용하려면 아래를 실행할 수 있습니다

if [ `grep -q PATTERN file.txt` ]; then
    echo found
else
    echo not found

이 논리는 모든 명령에 적용됩니다. 명령을 백틱 안에 넣으십시오 (탭 위의 버튼 또는 Esc 버튼의 아래쪽 또는 1 버튼의 왼쪽).


1
을 인용해야합니다 `grep -q PATTERN file.txt`. 그렇지 않으면 split + glob 연산자가 적용되며 문자 $IFS또는 와일드 카드 문자 가 포함 된 출력에 문제가 발생할 수 있습니다 . 보다 일반적으로 stdout에 비어 있지 않은 행을 하나 이상 출력 [ "`cmd`" ]하면 cmd(NUL 바이트를 출력하면 잠재적 인 문제가 있음) true를 반환합니다 . 즉, 쉘은 전체 출력을 메모리에 저장하고 완료 될 때까지 기다려야합니다. if cmd | grep -q .이와 관련 하여 대신에 사용 하는 것이 바람직 할 수있다.
Stéphane Chazelas

이 명령은 전혀 의미가 없습니다. -q스위치 의 목적은 의 출력 을 억제 하는 것입니다 grep. 당신은 말합니다 : file.txt에서 PATTERN을 확인하고 출력을 억제 한 다음 PATTERN을 찾았는지 여부에 따라 반환 상태를 설정하십시오. 그런 다음 반환 상태를 무시 하고 명령 출력 (비어 있어야 함)을 취하고 단어 분리 및 파일 glob 확장을 적용하고 (아무 인수도 발생하지 않음 ) 정확히 하나의 인수로 [(aka test) 명령 을 실행하십시오. , ]그 오류의 원인이되므로 - 그리고 다음, "을 (를) 찾을 수 없습니다"에코. @ StéphaneChazelas, 뭔가 빠졌습니까?
와일드 카드

1
@Wildcard, 당신 말이 맞아, 나는 분명히 간과했다 -q. 해당 주석은 의미가 [ `grep PATTERN file.txt ` ]있지만 [ "`grep -n PATTERN file.txt`" ]PATTERN이 빈 줄만 일치하면 주석에서 알 수 있듯이 더 좋습니다. 물론 여기는 if grep -q PATTERN file.txt당신이 원합니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.