OPEN STEP 4.2 OS 사용 중... 현재 다음 sed
명령을 사용하고 있습니다.
sed -n '1,/141.299.99.1/p' TESTFILE | tail -3
이 명령은 IP가 141.299.99.1인 파일에서 인스턴스를 찾고 그 앞의 3줄도 찾습니다. 모두 좋지만 첫 번째뿐만 아니라 해당 IP의 모든 인스턴스와 그 앞의 3줄도 찾고 싶습니다.
답변1
답변2
그것 으로 sed
슬라이딩 창문을 만들 수 있습니다.
sed '1N;$!N;/141.299.99.1/P;D'
그게 다야. 하지만 조심하세요. bash
미친 확장 동작!
인용하더라도!명령 기록에서 명령 문자열을 입력하는 것은 약간 이상할 수 있습니다. set +H;
이러한 상황이 발견되면 명령 앞에 가 붙습니다 . 그런 다음 다시 활성화하십시오.(그런데 왜???)나중에 하세요 set -H
.
물론 이것은 당신에게만 적용됩니다.예사용 bash
- 비록 나는 당신이 그렇다고 믿지 않지만. 그래요꽤 확실해당신은 csh
-(이것은 역사적 확장을 모방한 쉘 광기이지만 bash
아마도 c 쉘이 취하는 극단적인 것은 아닐 수도 있습니다). 그래서아마도작동 해야합니다 \!
. 나는 희망.
이것은 모두 이식 가능한 코드입니다.POSIX 설명세 가지 연산자는 다음과 같습니다.(이 설명의 존재를 2001년에야 확인했다는 점은 주목할 가치가 있습니다.)
[2addr]N
추가 자료를 원본 자료에서 분리하기 위해 내장된 유선을 사용하여 입력의 다음 줄(종료\n
줄을 뺀)을 패턴 공간에 추가합니다.\n
현재 줄 번호가 변경됩니다.
[2addr]P
패턴 공간(첫 번째 줄까지\n
)을 표준 출력에 씁니다.
[2addr]D
첫 번째 줄바꿈을 통해 패턴 공간의 초기 세그먼트를 삭제\n
하고 다음 루프를 시작합니다.
따라서 첫 번째 줄에서 패턴 공간에 추가 줄을 추가하면 다음과 같습니다.
^line 1s contents\nline 2s contents$
그런 다음 첫 번째 줄과 그 이후의 모든 줄에 - 마지막 줄을 제외하고 - 추가합니다.다른패턴 공간에 대한 선입니다. 따라서 다음과 같습니다.
^line 1\nline 2\nline 3$
IP 주소가 발견되면 P
첫 번째 개행 문자까지 인쇄되므로 여기에는 1행만 표시됩니다. 각 주기가 끝나면 D
동일한 콘텐츠를 선택하고 나머지 콘텐츠부터 시작합니다. 따라서 다음 주기는 다음과 같습니다.
^line 2\nline 3\nline 4$
...등. 귀하의 IP 주소가 이 세 주소 중 하나에서 발견되면 매번 가장 오래된 IP 주소가 인쇄됩니다. 그래서 당신은 항상오직처음 세 줄.
이것은 간단한 예입니다. 0으로 끝나는 각 숫자에 대해 세 줄짜리 버퍼를 인쇄하겠습니다.
seq 10 52 | sed '1N;$!N;/0\(\n\|$\)/P;D'
10
18
19
20
28
29
30
38
39
40
48
49
50
문제에 더 가까워지기 위해 0\n
줄 바꿈이나 패턴 공간의 끝 을 번갈아 가며 사용해야 하기 때문에 이것은 귀하의 경우보다 조금 더 복잡합니다. 그러나 앵커가 필요하기 때문에 미묘하게 다릅니다. 0$
패턴 공간이 계속 변하기 때문에 조금 어렵습니다.
앵커가 유연하면 출력도 유연하다는 것을 보여주기 위해 10과 52의 홀수 사례를 사용했습니다. 완전히 이식 가능하므로 알고리즘을 사용하고 다음을 수행하여 동일한 결과를 얻을 수 있습니다.
seq 10 52 | sed '1N;$!N;/[90]\n/P;D'
그리고 내 창을 0에서 9, 0, 3줄에서 2줄로 제한하면서 검색 범위를 넓힙니다.
어쨌든, 당신은 요점을 이해합니다.
답변3
이는 sed 이동 창을 사용하여 시뮬레이션하려는 시도입니다 grep -B3
.이 GNU sed 예제(그러나 POSIX 호환을 바랍니다 - @StéphaneChazelas에게 감사드립니다):
sed -e '1h;2,4{;H;g;}' -e '1,3d' -e '/141\.299\.99\.1/P' -e '$!N;D' file
처음 두 표현식은 여러 줄 모드 버퍼를 시작하고 첫 번째 일치 전의 이전 컨텍스트가 3줄 미만인 경우를 처리할 수 있도록 합니다. 중간(정규식 일치) 표현식은 원하는 일치 텍스트가 패턴 버퍼를 통해 전달될 때까지 창 상단에서 한 줄을 인쇄합니다. 마지막 항목은 $!N;D
입력 끝에 도달하지 않는 한 창을 한 줄 스크롤합니다.
답변4
사용 가능한 경우 다음을 사용할 수 있습니다.pcregrep:
pcregrep -M '.*\n.*\n.*\n141.299.99.1' file