コマンドラインの2番目の列の共有値に基づいて、列にカンマ区切り値のリストを含むテキストファイルを作成します。

コマンドラインの2番目の列の共有値に基づいて、列にカンマ区切り値のリストを含むテキストファイルを作成します。

一連のテキストファイルを作成したいと思います。各テキストファイルには、入力ファイルの列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シリーズのプログラミング言語の1つであるRakuでコーディングされたソリューションです。 Rakuの強みの1つは、Unicodeの高度なサポートです。

デフォルトで指定された問題は、すべてのキー/値のペアがハッシュに格納される問題keyです。新しい2番目の列(テキスト)要素が表示されるたびにそれを作成し、対応する最初の列(テキスト)要素を 。ハッシュは一意のままであるため、同じ後続の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

上記のコードは一度に1つの出力ファイルのみを開くため、「開いたファイルが多すぎます」というエラー(または速度低下)は発生せず、一度に1行だけメモリに保存されるため、関係なく動作し続けます。あなたの入力ファイルが大きいです。

$2入力が提供した例の値に基づいてグループ化されていると仮定しますが、実際のデータがそうでない場合は、最初に2番目のフィールドに基づいてソートします(例:)sort -k2,2 file | awk 'script'

関連情報