파일을 줄 접두사로 나누기


5

내 데이터는 다음과 같습니다

60  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
61  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
62  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
63  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
64  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

줄 접두사로 별도의 파일로 나누고 싶습니다.

file 60 contains all lines prefixed with "60"
file 61 contains all lines prefixed with "61"
...

내가 지금까지 생각해 낸 가장 좋은 아이디어는 모든 행 접두사를 grep 한 다음 반복하여 각 파일을 별도의 파일로 grep하는 것이지만 상당히 큰 파일이므로 시간이 오래 걸릴 수 있습니다. 아마도 루핑과 그 리핑보다 더 나은 방법이 있습니까? grep 그룹화의 방법? 각 섹션 사이에 마커가있는 경우 파일을자를 수있는 방법이 있다는 것을 알고 있지만 --- 그것이 최선의 방법인지 확실하지 않습니다.


또한 vim에서 할 수있는 방법이 있다면 괜찮습니다
slf

답변:


11

입력 파일이 호출 data되면 한 가지 해결책은 다음과 같습니다.

awk '{print>$1}' data

인은 awk, 첫 번째 필드 (열)를 호출한다 $1. 위의 내용은 각 입력 행을 반복하며 ( awk암시 적으로 수행) 이름이 첫 번째 필드 인 파일에 해당 행을 씁니다.

더 자세하게:

  • 명령은 중괄호로 묶습니다. 중괄호 앞에 한정자가 없으므로 명령은 모든 입력 행에서 실행됩니다.

  • print인수없이 명령 은 전체 입력 행을 인쇄합니다.

  • 기호 >는 출력을 파일로 리디렉션하는 것을 나타냅니다.

  • 파일 이름은 $1입력 행의 첫 번째 필드에있는 텍스트를 나타내는 것으로 지정됩니다 .

따라서이 명령은 60, 61입력 파일의 해당 행을 포함하는 등의 파일을 작성 합니다.

매우 큰 데이터 세트 처리

기본적으로 awk전체 명령이 완료 될 때까지 모든 파일 핸들을 열어 둡니다. 결과적으로 데이터 세트가 매우 크면 열린 파일 수에 대한 시스템 제한을 초과 할 수 있습니다. 가장 간단한 해결책은 쓰기 후에 각 파일을 추가하고 닫는 것입니다.

awk '{print>>$1; close($1)}' data

이것은 >>(추가)를 사용하기 때문에 기존 데이터 파일을 덮어 쓰지 않고 추가합니다. 원하는 것이 아닌 경우이 명령을 실행하기 전에 삭제하십시오.


bash에서 >>를 말하면 파일에 추가해야하지만 awk에서는 단일>이 추가됩니까?
slf

@slf awk는 같지 않습니다 bash. awk위의 명령과 같은 단일 호출 에서 첫 번째 사용 >filename은 덮어 씁니다 filename. >filename그러나 이후에을 사용 하면 추가 됩니다. 따라서 위의 코드 awk는 원하는 것을 수행해야합니다. 실행 >>하기 전에 파일에 awk있던 모든 것을 유지하면서 항상 추가하려는 경우에 사용하십시오 .
John1024

이것은 stackoverflow.com/questions/21093626/split-file-using-awk 와 같은 문제입니다 . close (fd)가 없으면 파일 핸들이 부족합니다.
slf

@slf 좋은 지적. 큰 데이터 세트를 처리하기 위해에 대한 버전을 답변에 추가했습니다 close.
John1024

@ l0b0 이상하게 들린다. Awk는 라인 단위로 처리합니다. 이 스크립트는 RAM을 소비 할 수있는 배열이나 기타 데이터 구조를 만들지 않습니다. 많은 양의 데이터를 처리하는 데 시간이 걸릴 수 있지만이 경우 RAM을 소비 할 이유가 없습니다. gawk 또는 mawk와 같은 다른 버전의 awk를 사용하여 결과가 다른지 확인 했습니까?
John1024
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.