대용량 파일을 패턴별로 두 부분으로 분할하는 방법은 무엇입니까?
예를 들어 file.txt
:
ABC
EFG
XYZ
HIJ
KNL
이 파일을 분할 XYZ
하여 file1
.XYZ
file2
답변1
이건 직업이야csplit
:
csplit -sf file -n 1 large_file /XYZ/
s
파일을 자동으로 분할하여 접두사가 있는 세그먼트를 생성 하고 f
등 의 단일 숫자 file
로 n
번호를 매깁니다 . file0
를 사용하면 /regex/
일치하는 행으로 분할되지만 포함되지는 않습니다 regex
. 다음으로 분할그리고regex
오프셋을 추가하여 일치하는 선을 포함합니다 +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
답변2
우리는 함께 awk
할 수 있습니다:
awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile
설명하다:첫 번째 인수( ) 는 후속 인수( )가 처리될 때 출력에 사용될 awk
파일 이름으로 변수를 정의합니다 . 프로그램은 변수( )에 의해 지정된 파일의 모든 행을 인쇄합니다. 패턴이 발견되면 출력 변수는 새 파일( )을 가리키도록 재정의되며, 이는 후속 데이터 라인을 인쇄하기 위한 대상으로 사용됩니다.out=file1
largefile
awk
out
{print >out}
XYZ
{out="file2}"
인용하다:
답변3
현대의 경우 위의 기본 답변 중 하나의 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 테스트 파일에서는 19~21초가 걸리는 반면 sed
/ 기반 cat
접근 방식은 39~47초가 걸립니다.)
답변4
GNU sed를 사용하여 이것을 시도해 보세요:
sed -n -e '1,/XYZ/w file1' -e '/XYZ/,${/XYZ/d;w file2' -e '}' large_file