파일을 줄 접두사로 나누기


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.