텍스트\라인 블록별로 Grep

텍스트\라인 블록별로 Grep

몇 줄이 포함된 텍스트가 있습니다. 그래서 여러 줄의 GREP을 만들어야 합니다. 예를 들어, 반복되는 텍스트가 있고 GREP에서 반복되는 키워드가 있는 줄을 가져와야 합니다.

grep -o "test|test2" textfile

내 텍스트:

123|never for your|test
123421|never for your|test2
123412|never for your|test3
12341|never for your|test4
12311|never for your|test2
123312312|never for your|test
123321312|never for your|test2

나는 다음을 가져야 한다:

123|never for your|test
123421|never for your|test2
123312312|never for your|test
123321312|never for your|test2

작동하지만 원하는 대로 작동하지 않습니다. 텍스트에서 모든 단어 "test" 및 "test2"를 검색합니다. 하지만 "test" 다음에 "test2"가 오는 패턴과 같은 텍스트 블록을 얻고 싶습니다. 어떤 아이디어가 있나요?

답변1

sed를 사용하는 간단한 쉘 스크립트. 두 번째 사례에 대한 줄 번호 목록을 만들고 첫 번째 사례에 대한 줄 번호와 비교합니다. 일치하는 쌍을 인쇄합니다. 첫 번째 인수를 파일 이름으로 사용합니다. 일치하는 패턴으로 두 번째 및 세 번째 인수를 사용하도록 쉽게 확장할 수 있습니다. findnext.sh로 저장하고 다음을 실행할 수 있습니다.

$ sh findnext.sh testfile

파일을 두 번만 통과하면 되기 때문에 속도가 빨라야 하며 완전히 이식 가능하다는 장점이 있습니다.

#!/bin/sh 
# Line numbers matching test1
mt2=$(sed -ne '/test1/=' < $1 | tr '\n' '/')

for l in $(sed -ne '/test/=' < $1); do
    nextline=$(expr $l + 1)
    [ "${mt2#*$nextline/}" != "$mt2" ] && sed -ne $l,${nextline}p <$1
done

답변2

grep -E 또는 egrep을 시도해 볼 수 있습니다. 이렇게 해보세요

#this will show lines that have test or test2
    grep -E "test|test2" file

test|test2와 같이 test 및 test2가 있는 행을 표시하려면 다음을 수행하십시오.

# This will show lines that has test|test2
    grep "test\|test2" file

답변3

awk이를 위한 도구가 될 수 있습니다.

awk '/test$/, /test2$/' < block-text-lines.txt 

일반적인 형태는 다음과 같습니다:

awk '/start-pattern/, /end-pattern/{command}'

그러나 명령 블록의 기본값은 인쇄이므로 시작 및 끝 패턴만 사용하면 됩니다.

체크아웃 man awk하거나Gnu Awk 사용자 가이드~을 위한방법자세한 세부 사항.

답변4

grep -A 1 "test$" in.txt | grep -B 1 "test2$"

grep 매뉴얼에서

-A NUM줄을 일치시킨 후 후행 컨텍스트의 NUM줄을 인쇄합니다.

-B NUM줄을 일치시키기 전에 선행 컨텍스트의 NUM줄을 인쇄합니다.

이 명령 grep -Pzo ".*test$\n.*test2$" in.txt도 작동하지만 매뉴얼에는 "이것은 매우 실험적이며 grep -P가 구현되지 않은 기능에 대해 경고할 수 있습니다."라고 되어 있습니다.

관련 정보