"의 작은 확장 질문입니다.큰 파일의 cat 라인 x에서 라인 y까지":
대용량 파일(2~3GB)이 있습니다. 나는 단지 "foo:"가 있는 줄에서 "goo:"가 있는 줄로 cat/print하고 싶습니다. "foo:"와 "goo:"가 파일에 한 번만 나타난다고 가정합니다. "foo:"는 "goo:"로 이어집니다.
이것이 지금까지 나의 접근 방식입니다.
- 먼저 "foo:" 및 "goo:"가 포함된 줄을 찾습니다.
grep -nr "foo:" bigfile
- 반품
123456: foo: hello world!
및654321: goo: good bye!
- 이러한 시작 및 끝 줄 번호와 차이점(654321-123456=530865)을 알고 나면 선택적 고양이를 수행할 수 있습니다.
tail -n+123456 bigfile | head -n 530865
내 질문은 줄 번호 상수를 표현식(예: grep...)으로 효율적으로 바꾸는 방법입니다.
간단한 Python 스크립트를 작성할 수 있지만 조합된 명령만 사용하여 구현하고 싶습니다.
답변1
sed -n '/foo/,/goo/p;/goo/q' <bigfile
그러면 해당 줄만 인쇄됩니다. 줄 번호를 원하면 하나를 추가할 수 있습니다 =
.
sed -n '/foo/=;/goo/=;//q' <bigfile
호출될 때 입력에 맞기 q
때문에 중요합니다 . 그렇지 않으면 infile이 끝까지 계속 읽혀집니다.q
sed
해당 줄을 인쇄하지 않으려면 foo/goo
다음을 수행할 수 있습니다.
GNU 사용 sed
:
sed -n '/foo/,/goo/!d;//!p;/goo/q
' <<\DATA
line1
foo
line3
line4
line5
goo
line7
DATA
산출
line3
line4
line5
기타:
sed -n '/foo/G;/\n/,/goo/!d;//q;/\n/!p
' <<\DATA
line1
foo
line3
line4
line5
goo
line7
DATA
산출
line3
line4
line5
그러나 어느 쪽이든 검색의 마지막 줄을 만나면 입력도 종료됩니다.
답변2
줄 번호를 얻기 위해 서브셸에서 무언가를 사용하는 현재 접근 방식을 포기하고 다른 유틸리티가 파일을 인쇄하도록 허용하는 데 동의하면 이 작업은 awk
순수한 방법으로 쉽게 수행 할 수 있습니다.
이 줄을 인쇄하려면~ 사이 foo:
goo:
행 자체 대신 다음을 사용할 수 있습니다 (원래는 여기에서 따왔어):
awk '/goo:/ { exit }; flag; /foo:/ { flag = 1 }' bigFile
위의 exit
s 는 끝 마커( goo:
) 를 볼 때 print
s 가 flag
true 인 경우 시작 마커()에 도달하면 flag
true(실제로)로 설정됩니다.1
foo:
그러나 출력에 토큰 줄을 포함하려는 경우 명령은 실제로 아래와 같이 더 간단합니다.@jasonwryan이 언급됨:
awk '/foo:/,/goo:/' bigFile
동일한 유틸리티를 사용하여 실제로 파일을 인쇄하는 대신 줄 번호를 얻으려고 애쓰는 경우 다음과 같이 열고 닫는 태그의 줄 번호를 얻을 수 있습니다.
awk '/foo:|goo:/ { print NR }' bigFile
답변3
대안 sed
:
sed '/foo/,$!d;/goo/q'
답변4
상수를 표현식으로 바꾸려면 다음을 사용할 수 있습니다.명령 대체.
명령의 출력을 표현식으로 바꾸려면 다음을 사용하십시오.$(command)
이 경우 적절한 명령줄은 다음과 같습니다.
tail -n+$(grep -nr "foo:" bigfile | cut -d':' -f1) bigfile | \
head -n$(($(grep -nr "goo:" bigfile | cut -d':' -f1)-$(grep -nr "foo:" bigfile | cut -d':' -f1)+1))
그러면 포함 줄부터 foo:
포함 줄(포함)까지 goo:
모든 줄이 인쇄됩니다.