Awk

ksh88 AIX 根據一列中的部分字元串匹配合併兩個文件

  • February 22, 2021

在 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_B有 2 列沒有標題:第 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_namedirectory_name/subfolderdirectory_name/subfolder/sub_subfolder中有重複的目錄名稱

我想要的是,在一個文件中,這個輸出(老實說,我不關心列的順序,只是它們都存在):

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

這似乎很簡單,但我無法弄清楚。我能得到的最接近的是從找到部分匹配的兩個文件中獲取使用者組和完整路徑名和行號,但我無法獲取目錄大小(來自的第 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 列中的第 2 列File_A中的部分匹配的每一行生成一個重複的列表File_B,例如:

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

directory_namedirectory_name/subfolder和各一個directory_name/subfolder/sub_subfolder

我已經嘗試了print我能想到的一切,但無濟於事……NR,FNR,i,$0,a[$NR],a[$FNR],a[$1],a[$2],$1,$2我也嘗試過使用printf,但也沒有用……

你想要的本質上是兩個數據庫表的連接。方便的是,有一個命令,恰當地命名為join.

這裡不需要awk。請注意,我既沒有ksh88也沒有 AIX;這是 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

第 1 步:添加一列filea,僅包含目錄路徑名的最後一部分:

$ 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 步:根據第 3 列 ( ) 和第 2列 ( ) 中的目錄名稱,使用join將其加入:fileb``filea``fileb

$ 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

可選步驟 4cut :如果您不想要,A將刪除第一列。

引用自:https://unix.stackexchange.com/questions/635452