답변:
로에게 awk
당신이 할 수 있습니다 :
awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile
설명 : 첫 번째 awk
인수 ( out=file1
)는 후속 인수 ( largefile
)가 처리 되는 동안 출력에 사용될 파일 이름으로 변수를 정의 합니다. awk
프로그램은 변수에 의해 지정된 파일에 모든 행을 출력한다 out
( {print >out}
). 패턴 XYZ
이 발견되면 출력 변수는 새 파일 ( {out="file2}"
) 을 가리 키도록 재정의되어 후속 데이터 라인을 인쇄하기위한 대상으로 사용됩니다.
참고 문헌 :
이것은 직업입니다 csplit
:
csplit -sf file -n 1 large_file /XYZ/
것 s
ilently 사전에 조각 만들기, 파일을 분할 f
IX을 file
하고 n
예를 들어, 하나의 숫자를 사용하여 umbered file0
등을 사용하는 것을 주 /regex/
일치하는지 선 포함에 분할,하지만하지 regex
. 로 분할하는 방법 과 라인 매칭을 포함 regex
A는 추가 +1
오프셋 :
csplit -sf file -n 1 large_file /XYZ/+1
이 두 개의 파일을 생성 file0
하고 file1
. 당신이 절대적으로 필요할 경우라는 이름의 수 file1
및 file2
당신은 항상에 빈 패턴을 추가 할 수 csplit
명령과 첫 번째 파일을 제거합니다
csplit -sf file -n 1 large_file // /XYZ/+1
생성 file0
, file1
그리고 file2
하지만 file0
당신이 안전하게 제거 할 수 있도록 비어 있습니다 :
rm -f file0
현대 에는 위 의 기본 답변 중 하나의 ksh
쉘 변형 (예 : 없음 sed
)이 있습니다 sed
.
{ read in <##XYZ ; print "$in" ; cat >file2 ;} <largefile >file1
그리고 ksh
단독으로 또 다른 변형 (즉,을 생략 cat
) :
{ read in <##XYZ ; print "$in" ; { read <##"" ;} >file2 ;} <largefile >file1
(순수한 ksh
솔루션은 성능이 뛰어나며 2.4GB 테스트 파일에서는 sed
/ cat
기반 접근 방식 의 39-47 초와 비교하여 19-21 초가 필요했습니다 ).
awk
합니다. 벤치 마크에서 어떻게 수행 되었습니까? 그리고 나는 ksh
항상이 싸움에서 이길 것이라고 확신 하지만 GNU sed
를 사용하고 있다면 너무 공평하지 않습니다 -GNU sed
의 -u
nbuffered는 POSIXLY에 대한 열악한 접근 방식입니다. 그것은-프로그램의 정규 작업을 느리게 할 필요가 없습니다-버퍼링은 괜찮습니다- sed
완료해야 할 모든 것은 설명자를 잃어 버립니다. 어떤 이유로 든 GNU는 그 정신을 뒤집습니다.
while
; 인쇄는 <##
재 지정 연산자 의 정의 된 부작용으로 내재적으로 수행됩니다 . 일치하는 줄만 인쇄하면됩니다. (쉘 기능 구현은 포함 / 제외를 지원하기 위해 가장 유연합니다.) 명시적인 while
루프는 상당히 느릴 것으로 예상되지만 확인하지는 않았습니다.
head
대신에 read
; 조금 느리게 보이지만 더 간결한 코드 : { head -1 <##XYZ ; { read <##"" ;} >file4 ;} <largefile >file3
.
쉬운 해킹은 대상 패턴의 일치 여부에 따라 STDOUT 또는 STDERR로 인쇄하는 것입니다. 그런 다음 셸의 리디렉션 연산자 를 사용하여 출력을 적절히 리디렉션 할 수 있습니다 . 예를 들어, 펄, 입력 파일을 가정하면이라 f
하고, 두 개의 출력 파일 f1
과 f2
:
분할 패턴과 일치하는 선을 버립니다.
perl -ne 'if(/XYZ/){$a=1; next} ; $a==1 ? print STDERR : print STDOUT;' f >f1 2>f2
일치하는 줄 포함 :
perl -ne '$a=1 if /XYZ/; $a==1 ? print STDERR : print STDOUT;' f >f1 2>f2
또는 다른 파일 핸들로 인쇄하십시오.
분할 패턴과 일치하는 선을 버립니다.
perl -ne 'BEGIN{open($fh1,">","f1");open($fh2,">","f2");}
if(/XYZ/){$a=1; next}$a==1 ? print $fh1 "$_" : print $fh2 "$_";' f
일치하는 줄 포함 :
perl -ne 'BEGIN{open($fh1,">","f1"); open($fh2,">","f2");}
$a=1 if /XYZ/; $a==1 ? print $fh1 "$_" : print $fh2 "$_";' f
XYZ
라인이 출력에 포함 되어야합니까 ?