다른 패턴 이전에 마지막으로 나타나는 패턴을 파악합니다.

다른 패턴 이전에 마지막으로 나타나는 패턴을 파악합니다.

두 가지 유형의 패턴이 포함된 거대한 파일이 있습니다.모드 1그리고모드 2, 모드 1이전에도 여러 번 이런 일이 있었을 수도 있습니다.모드 2나타나다. 나는 각각의 마지막 발생을 파악하고 싶습니다.모드 1각각 전에모드 2.

입력 파일:

some text
pattern1=1
some lines
pattern1=2
some lines
pattern1=3
some lines
pattern2
some lines
pattern1=4
some lines
pattern1=5
some lines
pattern1=6
some lines
pattern1=7
some lines
pattern2

원하는 출력:

pattern1=3
pattern1=7

grep내가 시도한 사이의 줄 수를 알 때모드 2그리고 이전 것모드 1:

grep -B400 "pattern2" | grep "pattern1"

하지만 두 패턴 사이의 줄 수에 관계없이 모든 파일에서 실행할 수 있는 고유한 명령이 필요합니다.

답변1

$ awk '/pattern1/{x=$0} /pattern2/{print x}' input
pattern1=3
pattern1=7

일치 항목(전체 줄)을 pattern1변수에 저장 x하고 pattern2일치 항목이 발생하면 인쇄합니다. 앞에 빈 줄이 있으면 pattern2빈 줄이 인쇄되며 pattern1, 이것이 바람직하지 않은지 여부를 감지하려면 더 많은 논리가 필요합니다. 입력의 끝이 앞에 오지 pattern1않는 모든 후행 a는 제거됩니다.pattern2

답변2

@thrig의 답변은 훌륭하지만 몇 가지 추가 테스트 사례를 처리하기 위해 몇 가지 수정을 했습니다. 다음 스크립트:

  • pattern2처음 발생하기 전에 발생하면 빈 줄이 인쇄되지 않습니다 pattern1.
  • pattern2after가 여러 번 발생하면 중복된 줄이 인쇄되지 않습니다 pattern1.

수정된 입력 파일:

pattern2
some text
pattern1=1
some lines
pattern1=2
some lines
pattern1=3
some lines
pattern2
pattern2
some lines
pattern1=4
some lines
pattern1=5
pattern2
some lines
pattern1=6
some lines
pattern1=7
some lines
pattern2

다음 스크립트는 귀하의 기사에서 설명하는 작업을 수행하는 것으로 나타납니다.

$ awk '/pattern1/{x=$0} length(x) && /pattern2/{print x;x=""}' file
pattern1=3
pattern1=5
pattern1=7

답변3

세 가지 grep호출:

  1. 원본 입력 파일과 ^pattern1=일치하는 행만 추출합니다.^pattern2$

    grep -e '^pattern1=' -e '^pattern2$' file
    
  2. 일치하는 행 ^pattern2$과 바로 앞의 행을 가져옵니다(비표준 -B옵션 사용).

    grep -B1 '^pattern2$'
    
  3. 일치하는 모든 행을 가져옵니다 ^pattern1=.

    grep '^pattern1='
    

모든 것을 한 번에:

grep -e '^pattern1=' -e '^pattern2$' file |
grep -B1 '^pattern2$' |
grep '^pattern1='

이는 다음과 동일한 엣지 케이스를 처리합니다.user000001의 답변, 즉 pattern2사이에 줄이 없는 줄이 많으면 pattern1중복된 줄을 출력하지 않으며 , pattern2파일 시작 부분에 있는 줄에 대해 빈 줄을 생성하지 않습니다.


사용 sed:

sed -e '/^pattern1=/ { h; d; }' \
    -e '/^pattern2$/ x' \
    -e '/^pattern1=/ !d' file
  1. 현재 행이 pattern1행인 경우 예약된 공간에 저장하고 폐기합니다.

  2. 현재 행이 pattern2행인 경우 예약된 공간을 바꿉니다.

  3. 현재 행이 현재 행이 아니면 pattern1삭제됩니다.

  4. (암시적) 현재 줄을 인쇄합니다. 이전 명령을 사용하면 현재 줄은 pattern1검색 줄로 인해 pattern2예약된 공간에서 교체된 줄이어야 합니다. 따라서 공간을 예약하면 반드시 행이 예약되므로 pattern2해당 pattern1행이 여러 번 출력되지 않습니다.

답변4

egrep "^pattern1|^pattern2" <file> | grep -B 1 "^pattern2" | grep "^pattern1"

첫 번째 egrep은 두 패턴 중 하나를 포함하는 줄만 가져옵니다(출력에서 알 수 없는 다른 줄은 모두 제거). 두 번째 grep은 Pattern2와 그 앞의 모든 행을 가져옵니다. 이는 앞에 패턴 1이 없는 패턴 2가 있는 행을 삭제하는 데 사용됩니다. 세 번째 grep은 나머지 Pattern1 행만 반환합니다.

관련 정보