답변:
먼저, 쉘이 패턴을 확장하지 못하도록 보호해야합니다. 가장 쉬운 방법은 작은 따옴표를 묶는 것입니다. 작은 따옴표는 백 슬래시를 포함하여 그 사이에 어떤 것도 확장하지 못하게합니다. 당신이 할 수없는 유일한 패턴에 작은 따옴표가 있습니다.
grep 'foo*' *.txt
작은 따옴표가 필요한 경우 '\''
(끝 문자열 리터럴, 리터럴 따옴표, 열린 문자열 리터럴) 로 쓸 수 있습니다 .
grep 'foo*'\''bar' *.txt
둘째, grep은 패턴에 대해 두 가지 구문을 지원합니다. 이전 버전의 기본 구문 ( 기본 정규 표현식 )은 대체 |
연산자 ( )를 지원하지 않지만 일부 버전에는 확장 기능이 있지만 백 슬래시로 작성됩니다.
grep 'foo\|bar' *.txt
이식 가능한 방법은 새로운 구문 인 확장 정규 표현식 을 사용하는 것 입니다. 선택하려면 -E
옵션 을 전달해야 grep
합니다. Linux에서는 egrep
대신 grep -E
다른 유형으로 입력 할 수도 있습니다 (다른 유니스에서는 별칭으로 만들 수 있음).
grep -E 'foo|bar' *.txt
여러 패턴 중 하나를 찾고있을 때의 또 다른 가능성은 (분리를 사용하여 복잡한 패턴을 작성하는 것과 달리) 여러 패턴을에 전달하는 것 grep
입니다. 각 패턴 앞에 -e
옵션 을 붙여서이를 수행 할 수 있습니다 .
grep -e foo -e bar *.txt
fgrep
또는 grep -F
작은 패턴의 경우 그 차이는 무시할 수 있지만 더 길어질수록 이점이 나타나기 시작한다.
grep -F
실제 성능 이점의 유무 는 grep 구현에 달려 있습니다. 그중 일부는 어쨌든 동일한 알고리즘을 적용하므로 -F
패턴을 구문 분석하는 데 걸리는 시간과 검색 시간에는 차이가 없습니다. -F
예를 들어 GNU grep은 속도가 빠르지 않습니다 (또한 grep -F
멀티 바이트 로케일에서 속도를 늦추는 버그가 있습니다 . 동일한 일정한 패턴 grep
이 실제로 훨씬 빠릅니다). 반면에 BusyBox grep은 -F
큰 파일 에서 많은 이점을 얻습니다 .
egrep
선행 grep -E
. GNU에만 국한된 것은 아닙니다 (확실히 Linux와는 아무런 관련이 없습니다). 실제로, 여전히 기본 grep
이 지원하지 않는 Solaris와 같은 시스템을 찾을 수 있습니다 -E
.
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을 사용했습니다. 이제 새로운 것을 배웠습니다. :)
정규식이 필요하지 않은 경우 다음 과 같이 여러 -e 매개 변수 를 사용 fgrep
하거나 사용하는 것이 훨씬 빠릅니다 grep -F
.
fgrep -efoo -ebar *.txt
fgrep
(또는 grep -F
)는 정규 표현식 대신 고정 문자열을 검색하기 때문에 일반 grep보다 훨씬 빠릅니다.
fgrep
더 이상 사용되지 않는 이 페이지의 주석도 참조하십시오 .
여러 패턴을 잡기위한 싸고 쾌활한 방법 :
$ echo "foo" > ewq ; echo "bar" >> ewq ; grep -H -f ewq *.txt ; rm ewq
-f
옵션은 여러 패턴을 가진 파일을 가져옵니다. 나중에 삭제하는 것을 잊을 수있는 임시 파일을 만드는 대신 쉘의 프로세스 대체를 사용하십시오.grep -f <(echo foo; echo bar) *.txt
파이프 ( |
)는 특수 쉘 문자이므로 이스케이프 처리 ( \|
)하거나 매뉴얼 ( man bash
)에 따라 인용 해야합니다 .
인용은 특정 문자 나 단어가 쉘에 특수한 의미를 제거하는 데 사용됩니다 . 특수 문자에 대한 특수 처리를 비활성화하고 예약어가 인식되지 않도록하고 매개 변수 확장을 방지하는 데 사용할 수 있습니다.
큰 따옴표로 문자를 묶으 면 따옴표 안에있는 모든 문자 의 리터럴 값 이 유지 됩니다.
따옴표가없는 백 슬래시 (
\
)는 이스케이프 문자입니다.
참조 : Bash에서 어떤 문자를 이스케이프해야합니까?
다음은 몇 가지 예입니다 (아직 언급되지 않은 도구 사용).
사용 ripgrep
:
rg "foo|bar" *.txt
rg -e foo -e bar *.txt
사용 git grep
:
git grep --no-index -e foo --or -e bar
참고 : 또한 같은 부울 식을 지원 --and
, --or
하고 --not
.
라인 당 AND 연산은 여러 AND 패턴으로 grep을 실행하는 방법을 참조하십시오.
파일 당 AND 연산은 파일 에 여러 문자열 또는 정규식이 모두 있는지 확인하는 방법을 참조하십시오.
날짜가 어리석게 형식화 된 액세스 로그가 있습니다 : [30 / Jun / 2013 : 08 : 00 : 45 +0200]
그러나 나는 그것을 다음과 같이 표시해야했습니다 : 30 / Jun / 2013 08:00:45
문제는 grep 문에서 "OR"을 사용하면 두 개의 별도 줄에 두 개의 일치 표현식이 수신된다는 것입니다.
해결책은 다음과 같습니다.
grep -in myURL_of_interest *access.log | \
grep -Eo '(\b[[:digit:]]{2}/[[:upper:]][[:lower:]]{2}/[[:digit:]]{4}|[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\b)' \
| paste - - -d" " > MyAccess.log
TL; DR : 여러 패턴 중 하나를 일치시킨 후 더 많은 작업을 수행하려면 다음과 같이 묶으십시오. \(pattern1\|pattern2\)
예 : 이름 'date'를 포함하는 변수가 String 또는 int로 정의 된 모든 장소를 찾고 싶습니다. (예 : "int cronDate ="또는 "String textFormattedDateStamp =") :
cat myfile | grep '\(int\|String\) [a-zA-Z_]*date[a-zA-Z_]* ='
을 사용 grep -E
하면 괄호 나 파이프를 벗어날 필요가 없습니다.grep -E '(int|String) [a-zA-Z_]*date[a-zA-Z_]* ='
이것은 나를 위해 작동
root@gateway:/home/sshuser# aws ec2 describe-instances --instance-ids i-2db0459d |grep 'STATE\|TAG'
**STATE** 80 stopped
**STATE**REASON Client.UserInitiatedShutdown Client.UserInitiatedShutdown: User initiated shutdown
**TAGS** Name Magento-Testing root@gateway:/home/sshuser#
여러 가지 방법이 있습니다.
grep 'foo\|bar' *.txt
egrep 'foo|bar' *.txt
find . -maxdepth 1 -type f -name "*.txt" | xargs grep 'foo\|bar'
find . -maxdepth 1 -type f -name "*.txt" | xargs egrep 'foo|bar'
세 번째 및 네 번째 옵션은 파일에서만 grep하고 디렉토리 .txt
이름에 포함 되지 않도록 합니다.
따라서 사용 사례에 따라 위에서 언급 한 옵션 중 하나를 사용할 수 있습니다.
감사!!
탭과 공백을 포함하는 여러 패턴이있는 경우 @geekosaur의 답변 에 추가 하려면 다음 명령을 사용하십시오.
grep -E "foo[[:blank:]]|bar[[:blank:]]"
[[:blank:]]
공백 또는 탭 문자를 나타내는 RE 문자 클래스는 어디에 있습니까?