파이프 문자로 여러 패턴의 패턴을 찾기 위해 grep하는 방법은 무엇입니까?

파이프 문자로 여러 패턴의 패턴을 찾기 위해 grep하는 방법은 무엇입니까?

여러 파일에서 두 패턴 중 하나와 일치하는 모든 줄을 찾고 싶습니다. 입력하여 원하는 패턴을 찾으려고 합니다.

grep (foo|bar) *.txt

|그러나 쉘은 이를 파이프로 해석 하고 bar실행 파일이 아닌 경우 불평합니다.

동일한 파일 세트에서 여러 패턴을 찾기 위해 grep하는 방법은 무엇입니까?

답변1

먼저, 쉘 확장으로부터 패턴을 보호해야 합니다. 가장 쉬운 방법은 작은따옴표로 묶는 것입니다. 작은따옴표는 그 사이의 내용이 확장되는 것을 방지합니다(백슬래시 포함). 그런 다음 수행할 수 없는 유일한 작업은 패턴에 작은따옴표를 사용하는 것입니다.

grep -- 'foo*' *.txt

(또한 GNU를 포함한 일부 구현이 호출된 파일 (shell에서 확장됨 )을 옵션으로 처리하는 것을 --방지하기 위해 닫는 옵션 태그 에 유의하십시오 (여기서는 옵션이 아닌 인수를 존중하더라도).grepgrep-foo-.txt*.txt

'\''작은따옴표가 정말로 필요한 경우 (끝 문자열 리터럴, 리터럴 인용, 열린 문자열 리터럴) 로 작성할 수 있습니다 .

grep -- 'foo*'\''bar' *.txt

둘째, grep은 최소한 두 가지 패턴 구문을 지원합니다. 이전 기본 구문(기본 정규식)는 대체( |) 연산자를 지원하지 않지만 일부 버전에서는 백슬래시로 작성된 확장자로 사용합니다.

grep -- 'foo\|bar' *.txt

이식 가능한 접근 방식은 최신 구문을 사용하는 것입니다.확장 정규식. 선택 -E하려면 옵션을 전달해야 합니다 (이전에는 별도의 명령²으로 이 작업을 수행했습니다).grepegrep

grep -E -- 'foo|bar' *.txt

여러 패턴 중 하나를 찾고 있는 경우(복잡한 패턴을 구축하기 위해 분리를 사용하는 대신), 또 다른 가능성은 여러 패턴을 에 전달하는 것입니다 grep. 각 패턴 앞에 Operate 옵션을 추가하면 됩니다 -e.

grep -e foo -e bar -- *.txt

또는 패턴을 여러 줄에 배치합니다.

grep -- 'foo
bar' *.txt

또는 이러한 패턴을 한 줄에 하나씩 파일에 저장하고 실행하십시오.

grep -f that-file -- *.txt

*.txt단일 파일로 확장하는 경우 grep여러 파일이 있을 때처럼 일치하는 줄 앞에 해당 이름이 붙지 않습니다. 이 문제를 해결하려면 일부 grep구현(예: GNU) 에서 grep이 옵션을 사용 -H하거나 모든 구현에서 /dev/null이를 추가 인수로 전달할 수 있습니다.


일부 구현은 , 또는 를 grep사용하여 Perl과 더 호환되는 구현을 지원하기도 합니다.-P향상된ksh 와일드카드 , -X...-K

² egrepPOSIX는 더 이상 사용되지 않으며 때로는 일부 시스템에서 더 이상 발견되지 않지만 POSIX 또는 GNU 유틸리티가 설치되지 않은 일부 다른 시스템(예: Solaris)에서는 , 또는 여러 줄 패턴이 지원되지 않으므로 egrep유일한 옵션입니다 ./bin/grep-e-f-E\|

답변2

egrep "foo|bar" *.txt

또는

grep "foo\|bar" *.txt
grep -E "foo|bar" *.txt

gnu-grep 매뉴얼 페이지를 선택적으로 인용합니다.

   -E, --extended-regexp
          Interpret PATTERN as an extended regular expression (ERE, see below).  (-E is specified by POSIX.)

Matching Control
   -e PATTERN, --regexp=PATTERN
          Use PATTERN as the pattern.  This can be used to specify multiple search patterns, or to protect  a  pattern
          beginning with a hyphen (-).  (-e is specified by POSIX.)

(...)

   grep understands two different versions of regular expression syntax: “basic” and “extended.”  In  GNU grep,  there
   is  no  difference  in  available  functionality  using  either  syntax.   In  other implementations, basic regular
   expressions are less powerful.  The following description applies to extended regular expressions; differences  for
   basic regular expressions are summarized afterwards.

처음에는 더 자세히 읽지 않았기 때문에 뉘앙스를 이해하지 못했습니다.

Basic vs Extended Regular Expressions
   In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead  use  the
   backslashed versions \?, \+, \{, \|, \(, and \).

나는 예제를 통해 배우기 때문에 항상 egrep과 불필요한 parens를 사용합니다. 이제 나는 새로운 것을 배웠습니다. :)

답변3

TC1이 말했듯 -F이 옵션을 사용할 수 있는 것 같습니다.

$> cat text
some text
foo
another text
bar
end of file

$> patterns="foo
bar" 

$> grep -F "${patterns}" text
foo
bar

답변4

정규식이 필요하지 않은 경우 다음과 같이 여러 -e 매개변수를 사용 fgrep하거나 사용하는 것이 더 빠릅니다.grep -F

fgrep -efoo -ebar *.txt

fgrep(또는 grep -F) 정규 표현식이 아닌 고정 문자열을 검색하기 때문에 일반 grep보다 훨씬 빠릅니다.

관련 정보