명령줄의 두 번째 열에 있는 공유 값을 기반으로 한 열에 쉼표로 구분된 값 목록이 포함된 텍스트 파일을 만듭니다.

명령줄의 두 번째 열에 있는 공유 값을 기반으로 한 열에 쉼표로 구분된 값 목록이 포함된 텍스트 파일을 만듭니다.

일련의 텍스트 파일을 만들고 싶습니다. 각 텍스트 파일에는 입력 파일의 열 2에 있는 공유 값을 기반으로 입력 파일의 열 1에 있는 값의 쉼표로 구분된 목록이 포함되어 있습니다.

입력 파일 형식:

CB-03-01-01     CB-03.1
CB-03-01-02     CB-03.1
CB-03-01-03     CB-03.1
CB-03-02-01     CB-03.2
CB-03-02-02     CB-03.2
CB-03-02-03     CB-03.2
CB-08-01        CB-08
CB-08-02        CB-08
CB-08-03        CB-08

원하는 출력: CB-03.1.txt

CB-03-01-01,CB-03-01-02,CB-03-01-03

CB-03.2.txt

CB-03-02-01,CB-03-02-02,CB-03-02-03

CB-08.txt

CB-08-01,CB-08-02,CB-08-03

당신이 제공할 수 있는 도움에 감사드립니다!

답변1

사용할 수 있는 명령은 다음과 같습니다.

awk '{a[$2]=a[$2]","$1} END {for(i in a) print substr(a[i],2) >i".txt"}' input_file

a연관 배열인 경우 substr이 함수는 배열 요소의 첫 번째 할당에서 선행 쉼표를 제거합니다.

의견에 따라 일부 버전 >i".txt"으로 교체 하고 열린 파일 처리기를 닫아야 할 수도 있습니다.>(i".txt"); close(i".txt")awk

답변2

사용행복하다(이전 Perl_6)

~$ raku -e 'my %h; for lines() { %h.push: .[1] => .[0] given .split(/ \s+ /) };
            for %h.sort() { 
                spurt( ( .key ~ ".txt" ).IO, $_.value.join(",") ~ "\n", createonly => True);
            };'  file.txt

위의 내용은 Perl 계열 프로그래밍 언어 중 하나인 Raku로 코딩된 솔루션입니다. Raku의 강점 중 하나는 유니코드에 대한 고급 지원입니다.

기본적으로 명시된 문제는 모든 키/값 쌍이 해시에 저장되는 문제 key입니다 . 새로운 두 번째 열(텍스트) 요소가 나타날 때마다 이를 만들고 해당하는 첫 번째 열(텍스트) 요소를 . 해시에서 고유한 상태로 유지되므로 동일한 후속 s는 동일한 으로 수정(또는 수정) 됩니다 .value%hkeyvaluekeysvaluekeypushappendkey

명령줄에서 입력을 받는 대신 하드코딩된 적절한 경로를 사용하여 다음 코드를 작성할 수 있습니다.

~$ raku -e 'my $in = "/path/to/file.txt".IO; my %h;
            for $in.lines() { %h.push: .[1] => .[0] given .split(/ \s+ /) };
            for %h.sort() { 
                my $out = IO::Spec::Unix.catpath($, $in.dirname, .key) ~ ".txt"; 
                spurt( $out,  $_.value.join(",") ~ "\n", createonly => True) };'

다른 옵션에는 위의 코드(작은따옴표 내)를 스크립트로 저장하고 명령줄에서 사용하는 것이 포함됩니다 raku script.raku. 위에서 언급한 것처럼 하드 코딩된 스크립트는 간단히IO::Spec필요에 따라 호출을 다음으로 변경하여IO::Spec::Win32IO::Spec::Cygwin

https://docs.raku.org/언어/hashmap#Mutable_hashes_and_immutable_maps
https://docs.raku.org/routine/split
https://raku.org

답변3

awk 사용(테스트되지 않음):

awk '
    $2 != prev {
        if ( out != "" ) {
            print "" > out
            close(out)
        }
        out = $2 ".txt"
        sep = ""
        prev = $2
    }
    {
        printf "%s%s", sep, $1 > out
        sep = ","
    }
    END {
        if ( out != "" ) {
            print "" > out
        }
    }
' file

위의 코드는 한 번에 하나의 출력 파일만 열므로 "열린 파일이 너무 많습니다"라는 오류(또는 속도 저하)가 발생하지 않으며 한 번에 한 줄만 메모리에 저장하므로 관계없이 계속 작동합니다. 귀하의 입력 파일이 큽니다.

$2입력이 제공한 예의 값을 기준으로 그룹화되어 있다고 가정하지만, 실제 데이터가 그렇지 않은 경우 먼저 두 번째 필드를 기준으로 정렬하세요(예: ) sort -k2,2 file | awk 'script'.

관련 정보