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 줄을 찾기를 제외하고는 모두 좋습니다. 그리고 처음 만이 아닙니다.
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 줄을 찾기를 제외하고는 모두 좋습니다. 그리고 처음 만이 아닙니다.
답변:
다음 grep -B3
은 이 GNU sed 예제를 기반으로 sed moving window를 사용하여 에뮬레이션하려는 시도입니다 (그러나 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
은 입력이 끝날 때를 제외하고 창을 한 줄씩 스크롤합니다.
-e
GNU 고유의 것이 아닙니다. POSIX / 휴대용이 되려면, 그 이후에는 아무것도 없어서 }
필요합니다 ;
.
-e '1h;2,4{H;g;}' -e '1,3d'
합니까? 테스트 할 GNU가 아닌 시스템 --posix
이 없으며 GNU sed 스위치는 신경 쓰지 않는 것 같습니다.
sed
전통적인 Unix sed의 후손 인 가보 툴을 사용하여 다른 구현을 테스트 할 수 있습니다 . POSIX / Unix 사양 sed
은 pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html에 있습니다.
grep
더 나은 일을 할 것입니다 :
grep -B 3 141.299.99.1 TESTFILE
-B 3
수단은 각 경기 전에 세 줄을 인쇄합니다. --
각 줄 그룹 사이에 인쇄 됩니다. 이를 비활성화하려면 사용하십시오 --no-group-separator
.
이 -B
옵션은 GNUgrep
및 대부분의 BSD 버전에서도 지원됩니다 ( OSX , FreeBSD , OpenBSD , NetBSD )에서도 지원되지만 기술적으로 표준 옵션은 아닙니다.
으로 sed
당신은 슬라이딩 윈도우를 할 수 있습니다.
sed '1N;$!N;/141.299.99.1/P;D'
그렇습니다. 그러나 인용 할 때조차도bash
확장하는 미친 행동 !
! 명령 기록에서 명령 문자열로 들어가면 약간 미친 듯이 보일 수 있습니다. set +H;
이 경우 명령 앞에 접두사를 붙 입니다. 다음을 다시 사용하려면 (??? 왜하지만) 할 set -H
나중에.
물론, 당신 이 사용 bash
하고있는 경우에만 적용됩니다 . 난 꽤 특정 작업중인 csh
- (누구의 미친 행동 쉘 될 일이있는 bash
C 쉘은 그것을했다 극단의 역사 확장과 모방을하지만, 아마) . 그래서 아마 a는 \!
작동합니다. 나는 희망.
그것은 모든 휴대용 코드입니다 : POSIX는 설명 따라서 세 개의 연산자 : (I 만이 설명을 확인했다고 지적 그것의 가치가로 2001 년 초와 같은 존재하지만)
[2addr]N
추가 된 재료를 원래 재료와 분리하기 위해\n
내장 된\n
ewline을 사용하여 다음 입력 라인 (종료 ewline을 줄임)을 패턴 공간에 추가합니다. 현재 줄 번호가 변경됩니다.
[2addr]P
첫 번째\n
ewline 까지의 패턴 공간 을 표준 출력에 씁니다.
[2addr]D
첫 번째\n
ewline을 통해 패턴 공간의 초기 세그먼트를 삭제하고 다음주기를 시작하십시오.
따라서 첫 번째 줄에서 패턴 공간에 추가 줄을 추가하면 다음과 같습니다.
^line 1s contents\nline 2s contents$
그런 다음 첫 번째 줄과 그 이후의 모든 줄에-마지막 줄을 제외하고- 패턴 공간에 다른 줄을 합니다. 따라서 다음과 같이 보입니다.
^line 1\nline 2\nline 3$
IP 주소가 발견 P
되면 첫 번째 줄 바꿈까지 찢으십시오. 모든 사이클이 끝나면D
은 똑같이 뛰어 들고 남아있는 것을 다시 시작합니다. 다음주기는 다음과 같습니다.
^line 2\nline 3\nline 4$
...등등. 당신의 IP가 그 세 가지 중 하나에서 발견되면, 가장 오래된 것-매번 인쇄됩니다. 그래서 당신은 항상 단 세 줄의 앞.
다음은 간단한 예입니다. 0으로 끝나는 모든 숫자에 대해 3 줄 버퍼가 인쇄됩니다.
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 줄로.
어쨌든, 당신은 아이디어를 얻습니다.
sed '...' $filename
. 그건 그렇고-나는 당신의 검색 문자열에서 마침표를 남겼지 만 실제로는 패턴의 마침표가 아닙니다-그것들은 단일 문자를 나타냅니다. 당신은 아마 어떻게해야 oct\.oct\.oct\.oct
그들이 그렇게 그들을 탈출 에만 기간을 일치합니다.
에 대한 옵션 이 없다고 언급 했으므로 Perl (예 :)을 사용하여 4 줄의 창을 슬라이딩 할 수 있습니다.-B
grep
perl -ne '
push @window,$_;
shift @window if @window > 4;
print @window if /141\.299\.99\.1/
' your_file
Ramesh의 답변은와 비슷한 작업을 수행 awk
합니다.
쉘 자체에서 다른 grep이 아닌 응답과 동일한 기본 접근 방식을 구현할 수 있습니다 (이는 비교적 최근의 쉘을 지원한다고 가정합니다 =~
).
while IFS= read -r line; do
[[ $line =~ 141.299.99.1 ]] && printf "%s\n%s\n%s\n%s\n" $a $b $c $line;
a=$b; b=$c; c=$line;
done < file
또는 전체 파일을 배열에 넣을 수 있습니다.
perl -e '@F=<>;
for($i=0;$i<=$#F;$i++){
print $F[$i-3],$F[$i-2],$F[$i-1],$F[$i] if $F[$i]=~/141.299.99.1/
}' file
awk '/141.299.99.1/{for(i=1;i<=x;)print a[i++];print} {for(i=1;i<x;i++)
a[i]=a[i+1];a[x]=$0;}' x=3 filename
이 awk
솔루션 에서는 현재 패턴 앞에 항상 3 줄을 포함하는 배열이 사용됩니다. 따라서, 패턴이 일치하면, 현재 패턴과 함께 배열 내용이 인쇄된다.
테스팅
-bash-3.2$ cat filename
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
141.299.99.1
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
10.0.0.10
141.299.99.1
10.0.0.11
10.0.0.12
10.0.0.13
10.0.0.14
10.0.0.15
10.0.0.16
141.299.99.1
10.0.0.17
10.0.0.18
10.0.0.19
명령을 실행하면 출력은 다음과 같습니다.
10.0.0.2
10.0.0.3
10.0.0.4
141.299.99.1
10.0.0.8
10.0.0.9
10.0.0.10
141.299.99.1
10.0.0.14
10.0.0.15
10.0.0.16
141.299.99.1
이들의 대부분에서, /141.299.99.1/
도 (예)를 일치 141a299q99+1
또는 141029969951
때문에.
정규식에서 모든 문자를 나타낼 수 입니다.
사용은 /141[.]299[.]99[.]1/
안전합니다, 당신은 반드시 일치하지 않을 시작 부분에 추가 컨텍스트를 추가하기 위해 전체 정규 표현식의 끝 수 3141.
, .12
, .104
, 등