awk 다른 파일의 특정 열에서 동일한 내용을 가진 모든 줄을 분리하는 방법

awk 다른 파일의 특정 열에서 동일한 내용을 가진 모든 줄을 분리하는 방법

다음과 같은 큰 csv 파일(Test.csv)이 있습니다.

1,2,3,A,5
1,2,3,B,5
1,2,3,E,5
1,2,3,D,5
1,2,3,Z,5
1,2,3,B,5

네 번째 열의 내용이 다른 파일에 있는 행을 인쇄하고 싶습니다. 실제로 동일한 콘텐츠가 포함된 이러한 행을 네 번째 열 콘텐츠라는 이름의 새 csv 또는 txt 파일에 결합해야 합니다. 예를 들어:

산출:

파일 A

1,2,3,A,5
1,2,3,A,5
1,2,3,A,5

문서 B

1,2,3,B,5
1,2,3,B,5

입력 파일이 크기 때문에 네 번째 열에 얼마나 많은 패턴이 있는지 알 수 없습니다. 4열에는 단어만 포함되고, 다른 열에는 단어 및/또는 숫자가 포함됩니다.

경험이 없어서 비슷한 질문을 찾아보고 다음 코드도 시도해 보았습니다.

awk 'NR==FNR{a[$4]=NR; next} $NF in a {print > "outfile" a[$NF]}' Test.csv

그러나 아무것도 작동하지 않습니다. 누구든지 나를 도와줄 수 있나요? 미리 감사드립니다.

답변1

이는 POSIX 순서 및 awk를 사용하는 모든 UNIX 시스템의 모든 쉘에서 효율적으로 작동합니다.

$ sort -t, -k4,4 test.csv |
    awk -F, '$4!=prev{close(out); out="File"$4; prev=$4} {print > out}'

$ head -n 20 File*
==> FileA <==
1,2,3,A,5

==> FileB <==
1,2,3,B,5
1,2,3,B,5

==> FileD <==
1,2,3,D,5

==> FileE <==
1,2,3,E,5

==> FileZ <==
1,2,3,Z,5

참고할 사항:

  1. 일부 awks에서는 출력 리디렉션 오른쪽의 표현식 주위에 괄호가 필요합니다.
  2. 출력 파일을 닫지 않으면 일부 awks가 실패하므로 12개 이상의 출력 파일을 얻으면 너무 많은 열린 파일을 유지하려고 시도합니다.
  3. 허용되는 모든 awks에서 여러 개의 열린 출력 파일을 유지하는 것은 매우 비효율적이며
  4. 모든 awks에서 이 문제를 해결하기 위해 출력 파일을 한 줄씩 닫는 것은 매우 비효율적입니다.

답변2

출력 파일 이름의 필드만 사용할 수 있어야 합니다. 간단한 해결책:

awk -F, '{print > ("file_" $4 ".csv")}' Test.csv

이것은 적어도 GNU awk에서 작동하고 file_A.csv등을 생성합니다. file_B.csv이렇게 하면 모든 출력 파일이 열린 상태로 유지되며, 파일이 많을수록 특히 프로세스당 열린 파일 제한에 도달할 때 속도가 느려집니다.

-F,필드 구분 기호를 쉼표로 설정하세요.

당신이 보여주는 스크립트가 무엇을 해야하는지 잘 모르겠습니다.

답변3

이 같은:

$ awk -F, '{ print $0 >> "file-" $4 ".txt"; }' ./tmp.txt

@ilkkachu의 답변에서 언급했듯이 플래그는 -F필드 구분 기호를 기본 공백 문자에서 쉼표로 변경하는 것입니다. 파일이 존재하는 경우 덮어쓰지 않도록 >>대신  사용해야 합니다 .>

답변4

파이썬

#!/usr/bin/python
uni=[]
k=open('file.txt','r')
for i in k:
    
    g=i.split(",")[3].strip()
    if g not in uni:
        uni.append(g)



for m in uni:
    f=open("{0}.txt".format(m),'w')
    l=open('file.txt','r')
    for d in l:
        if m in d.split(",")[3].strip():
            f.write(d)

awk는 이미 최고의 솔루션을 제공하고 있습니다. 이것은 단지 저의 시도일 뿐입니다.

for i in `awk -F "," '{if(!seen[$4]++)print $4}' file.txt`; do awk -v i="$i" -F "," '$4==i{print $0}' file.txt >$i.txt; done

관련 정보