ksh88 AIX は、1 つの列の部分文字列一致に基づいて 2 つのファイルをマージします。

ksh88 AIX は、1 つの列の部分文字列一致に基づいて 2 つのファイルをマージします。

AIXシステムでksh88を使用して多くのことを試しましたが、何も機能しませんでした。

File_Aヘッダーのない2つの列があります。列1にはディレクトリを作成したユーザーグループ、列2にはフルファイルパスがあります。たとえば、次のようになります。

Userwh0c4r35     /fake/file/path/directory_name
User1234567      /another/file/path/different_dir
User0987654      /some/other/path/another_name

File_B2つの列があり、ヘッダーはありません。列1にはディレクトリサイズ(MB)、列2にはディレクトリの部分パス名があります。たとえば、次のようになります。

2183.31     directory_name
1750.09     directory_name/subfolder
1028.14     directory_name/subfolder/sub_subfolder
3658.97     different_dir
2159.62     different_dir/subfolder
1001.01     different_dir/different_subfolder 

など。

問題はFile_B(つまりdirectory_name、、、、directory_name/subfolder...)directory_name/subfolder/sub_subfolderに重複したディレクトリ名があることです。

私が望むのは、ファイル内の次の出力です(正直なところ、列の順序は気にせず、列がすべて存在するということだけです)。

Userwh0c4r35     /fake/file/path/directory_name     2183.31
User1234567      /another/file/path/different_dir   3658.97

これは十分簡単なようですが、私はそれを見つけることができませんでした。私が得る最も近い方法は、部分的に一致する2つのファイルからユーザーグループ、フルパス名、および行番号を取得することです。ただし、ディレクトリサイズ(列1 File_B)はインポートできません。

私に近づいていますが、まだそこに到達していないコードは次のとおりです(SOとさまざまなオンラインチュートリアルで一緒に編成)。

awk '
NR==FNR {
    a[$2]=$1
    next
}
{
    for(i in a) 
        if($2 ~ i) 
            {print $2,a[$2],$1} 
}' file_B file_A 

File_Aの列2がFile_A部分的に列2に一致する各行に重複する項目があるリストを作成しますFile_B。たとえば、次のようになります。

Userwh0c4r35     /fake/file/path/directory_name
Userwh0c4r35     /fake/file/path/directory_name
Userwh0c4r35     /fake/file/path/directory_name

directory_namedirectory_name/subfolder、、、およびそれぞれ1つdirectory_name/subfolder/sub_subfolder

print私が考えることができるすべてを試してみましたが、役に立ちませんでした...NR,FNR,i,$0,a[$NR],a[$FNR],a[$1],a[$2],$1,$2私も試してみましたが、printfやはり効果がありませんでした...

ベストアンサー1

あなたが望むのは、本質的に2つのデータベーステーブルを結合することです。便利なことに、これを実行する適切な名前のコマンドがありますjoin

ここでは必要ありませんawk。私はAIXもAIXもありませんksh88。これはLinuxのBashですが、すぐに確認しました。AIX マニュアルそしてそれがうまくいくはずだと思いました。

私は次のテスト環境を準備しました。

$ cat filea
Userwh0c4r35     /fake/file/path/directory_name5
Userwh0c4r36     /fake/file/path/directory_name6
Userwh0c4r37     /fake/file/path/directory_name7
$ cat fileb
1234    directory_name5
2345    directory_name6
3456    directory_name7

ステップ1filea:ディレクトリパス名の最後の部分のみを含む列を追加します。

$ sed 's|\(.*\)/\(.*\)|\1/\2 \2|' filea > filea.tmp
$ cat filea.tmp
Userwh0c4r35     /fake/file/path/directory_name5 directory_name5
Userwh0c4r36     /fake/file/path/directory_name6  directory_name6
Userwh0c4r37     /fake/file/path/directory_name7  directory_name7

ステップ2:両方のファイルをディレクトリ名でソートします(これを指摘したMark Plotnickに感謝します)。

$ sort -k3 filea.tmp > filea.tojoin
$ sort -k2 fileb > fileb.tojoin

ステップ3:ANDを使用して、列3()と列2()のディレクトリ名に基づいてjoin結合します。filebfileafileb

$ join -1 3 -2 2 filea.tojoin fileb.tojoin > result
$ cat result
directory_name5 Userwh0c4r35 /fake/file/path/directory_name5 1234
directory_name6 Userwh0c4r36 /fake/file/path/directory_name6  2345
directory_name7 Userwh0c4r37 /fake/file/path/directory_name7  3456

オプションのステップ4cutAは、望ましくない場合は最初の列を削除します。

おすすめ記事