일치하는 모든 파일 표시


71

grep --before-context 5 경기 전 5 줄을 보여줍니다.

경기 전에 모든 것을 보여주고 싶습니다. 일하는 것은 효과가 있지만
그렇게 grep --before-context 99999999전문적이지는 않습니다.

일치하는 모든 파일을 표시하는 방법?

답변:


95

Sed 가 더 좋습니다.

그냥 해:

sed '/PATTERN/q' FILE

다음과 같이 작동합니다.

각 줄마다 다음과 일치하는지 확인합니다 /PATTERN.

  • 그렇다면, 우리는 그것을 인쇄하고 종료
  • 그렇지 않으면, 우리는 그것을 인쇄

가장 효율적인 솔루션입니다.이 즉시 PATTERN보이면 종료됩니다. 가 없으면 qsed는 파일의 나머지 부분을 계속 읽고 아무 ​​것도 수행하지 않습니다. 큰 파일의 경우 차이를 만들 수 있습니다.

이 트릭을 사용하여 에뮬레이션 할 수도 있습니다 head.

sed 10q FILE

시도는 단지 파일의 첫 번째 줄을 출력합니다. 비록 일치하는 것은 38 번째 줄에 있습니다.
Nicolas Raoul

나를 위해 잘 작동합니다. 실제 입력 및 출력의 예를 제시 할 수 있습니까? 그리고 당신이 실행중인 명령은 그대로입니다.
Mikel

나는 당신이 그것을 편집하기 전에 당신의 명령을 시험해 보았습니다. sed '/ PATTERN / p; q'FILE
Nicolas Raoul

7
패턴 일치로 줄을 인쇄하지 않으려면 어떻게해야합니까?
tommy.carstensen

4
@ tommy.carstensen : sed '/PATTERN/Q' FILE일치하는 줄을 건너 뜁니다. QGNU 확장이므로 sed에서는 작동하지 않습니다.
Alex O

37

sed grep의 기능 대부분을 대체 할 수 있습니다.

sed -n '1,/<pattern>/ p' <file>

즉, 패턴이 일치 할 때까지 첫 번째 줄에서 인쇄합니다.

몇 가지 범위 예제

sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2

3
이 명령은 좋지만 더 잘할 수 있습니다. 이렇게하면 전체 파일을 읽지 만 일치하는 것을 발견하자마자 종료 할 수 있습니다.
Mikel

3
패턴 일치로 줄을 인쇄하지 않으려면 어떻게해야합니까?
tommy.carstensen

34

일치하는 것을 포함하여 인쇄하십시오.

awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename

일치 항목을 제외하고 최대 인쇄 :

awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename

11
Q시원하지만 gnu 고유의 afaik sed -n '/pattern/!p;//q'은 더 휴대하기 쉽습니다 .
don_crissti

. @don_crissti : 나는 그것이 어떻게 작동하는지 좀 궁금하지만 저는 믿습니다 : 당신은 내가 그것이 좋은 일 (생각, 그것을 답을해야 !합니다 p라인에 적용 되지 일치 pattern하지만, 다음은 //q나 ... 혼란
JWD

2
@don_crissti : 아, 알았어요 — //"이전 정규 표현식"을 의미합니다 ( "빈 문자열과 일치"를 의미한다고 생각했습니다). 동일한 솔루션의 짧은 버전은 다음과 같습니다 sed -n '/pattern/q;p.
jwd

@jwd-실제로, 더 짧습니다. 👍
don_crissti

1

다음과 같은 순수한 GNU grep방법은 효율적이지 않습니다.

세 개의 s를 사용하여 파일 막대 에서 문자열 " foo " 의 첫 번째 인스턴스 까지 모든 것을 검색 하십시오 .grep

grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar

" foo " 의 마지막 인스턴스와 일치 :

grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar

참고 : 마지막에 대한 자세한 내용은 grep:에서 찾을 수 있습니다 필요한 여러 줄 검색을위한 정규식 (GREP) .


grep단순히 단일 sed호출을 실행해야 할 때 왜 7 초 (+ pcre) 를 사용하고 싶습니까 sed 'x;/./G;//!x;/foo/p;//s/.*//;x;d'?
don_crissti

@ don_crissti, sed코드 자체 답변의 가치가 있거나 다른 코드 중 하나에 추가 될 수 있습니다. 7 다시 grepS :이 있었으므로 아무 grep대답은 ... (플러스, 대답은 할 수 없다 보여 왜 안.)
AGC

내 코드가 아니고 그냥 클릭하십시오 ... 내 코드 인 경우에도 여기에 Q로 대답하지 않으므로 답변으로 게시하지 않습니다.
don_crissti

1

위의 Mikel의 답변에 추가 ...


모든 행을 인쇄하려면 포함 최대 아니지만 , 첫 번째 줄 FILE포함을 PATTERN시도 :

  • sed '/.*PATTERN.*/{s///;q;}' FILE

이것은 패턴을 포함하는 전체 행과 일치하고이를 빈 행으로 바꾸고 나머지 파일을 처리하지 않고 종료합니다.


추신:

마지막에 (다른 도구를 사용하지 않고) 추가 줄 바꿈이 인쇄되지 않도록 생각할 수있는 가장 쉽고 명확한 방법은 sed를 다시 실행하고 새 마지막 줄을 삭제하는 것입니다.

sed '/.*PATTERN.*/{s///;q;}' FILE | sed '$d'

... 어쨌든 우리는 이제 그 라인을 삭제하고 있기 때문에 이전 작업이 중복되어 다음과 같이 단순화 할 수 있습니다.

sed '/PATTERN/q' FILE | sed '$d'

Glenn의 답변과 저의 의견은 단일 sed호출 로 수행하는 방법을 보여줍니다 .
don_crissti

(감사는가 -. 나는 AGC의 대답에 귀하의 코멘트를 참조 않았지만, 하나가 다른 하나를 놓친 또는 내 뇌가 더블 네거티브를 싫어하기 때문에 무 지방) 나는 모두이 사용 된 이래 tcshbash별명, 나는 확인에 필요한 I 표준과 GNU 모두에서 작동하는 비교적 간결한 한 줄 솔루션을 가지고있었습니다 sed(이동성을 위해). 귀하의 기여가 매우 잘 충족 될 수있는 모든 요구 사항. sed 매우 드물게 사용하는 사람으로서 , 가장 중요한 요구 사항은 몇 년 전부터 쉽게 편집하거나 용도를 바꾸고 싶을 때 빠르게 이해할 수있는 것이 었습니다.
Jim Grisham

1

일상 업무에서 기본 도구 만 기억하고 덜 우아하고 덜 효율적인 솔루션을 기꺼이 받아들이려는 사람들에게 :

head -n $(grep -n pattern filename | cut -d: -f1) filename

이 명령이 스크립트를위한 것이라면 더 우아하고 (아마도 효율적인) 솔루션을 찾을 것입니다. 이것이 일회성 명령이거나 스크립트를 버리면 상관 없습니다.


1
좋은 생각이지만 하나 할 때 세 가지 명령.
Mikel

1
기본을 아는 것은 실제로 매우 좋습니다. 그러나 작업에 적합한 도구를 아는 것이 좋습니다.
soulmerge

이 명령이 스크립트를위한 것이라면 더 우아하고 (아마도 효율적인) 솔루션을 찾을 것입니다. 이것이 일회성 명령 (또는 버리기 스크립트)이라면 상관하지 않습니다.
lesmana

0

다음 중 하나를 사용할 수도 있습니다.

tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac 

또는

tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac

또는

tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac

첫 번째 옵션은 OP가 제안한 것과 매우 유사하며 파일에서 줄을 계산하여 컨텍스트 전에 충분한 줄을 표시하도록합니다.

두 번째 옵션은 첫 번째 일치 행 번호를 검색하고 (내부 'head'를 변경하여 변경할 수도 있음) 해당 번호에서 head를 사용합니다

마지막 옵션은 모든 새 줄을 일치 항목으로 바꾸고 두 개의 인접한 일치 항목을 새 줄로 바꿉니다. 이 결과는 두 개의 일치 항목 사이의 모든 텍스트 블록에 대한 줄입니다. 그런 다음 'head'를 사용하여 첫 번째 줄 (텍스트 블록을 첫 번째로 일치시킬 때까지 일치)을 선택하고 각 일치 항목을 새 줄로 다시 변환합니다. 이 옵션은 파일이 다음 형식 인 경우에만 작동합니다

pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern 
texttexttext
texttexttexttexttexttexttexttexttext

기타 등등


2
특히 sed하단에있는 명령이 엉뚱 하기 때문에 어떻게 작동하는지 설명해보십시오 .
strugee

첫 번째 옵션은 OP가 제안한 것과 매우 유사합니다.
필러
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.