"cat"ファイルのすべての行をペアに拡張するためのコマンドラインツール

次のファイルがあるとします(sample.txtと呼ばれます)。

Row1,10
Row2,20
Row3,30
Row4,40

私はこのファイルからストリームを処理できるようにしたいです。これは基本的に4行すべてをペアで組み合わせたものです(したがって、合計16行にする必要があります)。たとえば、出力は次のようなストリーミング(つまり効率的な)コマンドを探しています。

Row1,10 Row1,10
Row1,10 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row2,20 Row1,10
Row1,20 Row2,20
...
Row4,40 Row4,40

私の使用例は、この出力を別のコマンド(awkなど)にストリーミングして、このペアの組み合わせに関するいくつかのメトリックを計算したいと思います。

awkでこれを行う方法はありますが、END {}ブロックを使用することは、基本的にファイルを出力する前にファイル全体をメモリに保存することです。サンプルコード:

awk '{arr[$1]=$1} END{for (a in arr){ for (a2 in arr) { print arr[a] " " arr[a2]}}}' samples/rows.txt 
Row3,30 Row3,30
Row3,30 Row4,40
Row3,30 Row1,10
Row3,30 Row2,20
Row4,40 Row3,30
Row4,40 Row4,40
Row4,40 Row1,10
Row4,40 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row1,10 Row1,10
Row1,10 Row2,20
Row2,20 Row3,30
Row2,20 Row4,40
Row2,20 Row1,10
Row2,20 Row2,20

ファイルをメモリに保存してからENDブロックに出力せずにこれを行うための効率的なストリーミング方法はありますか?

ベストアンサー1

ファイル全体を配列に保存する必要がないように、awkで実行する方法は次のとおりです。これは基本的にterdonのアルゴリズムと同じです。

必要に応じて、コマンドラインで複数のファイル名を指定することもでき、各ファイルを個別に処理して結果を一緒にリンクします。

#!/usr/bin/awk -f

#Cartesian product of records

{
    file = FILENAME
    while ((getline line <file) > 0)
        print $0, line
    close(file)
}

私のシステムでは、terdonのPerlソリューション時間の約3分の2で実行されます。

おすすめ記事