我有以下文件:
cat fileA.txt
seattle 1991 west
atlanta 1993 west
turlock 1998 west
marysville 2004 south
newyork 2007 north
canada 2004 west
第二個文件如下圖所示:
cat fileB.txt
popular
someWhatPopular
boring
popular
popular
popular
我想得到以下輸出fileB.txt
:
popular popular popular someWhatPopular boring popular
所以本質上我想排序fileB.txt
到fileA.txt
第三列
我嘗試了以下程式碼:
#!/bin/bash
sort -s -k3,3 fileA.txt fileB.txt
但這沒有用。有什麼建議麼?我對任何不需要硬編碼的東西都持開放態度。 Bash/awk/sed 等
答案1
這是一個比linux更重要的資料結構問題。您需要在兩個表中使用一個公共條目(鍵)來連結它們,就像在任何「資料庫」中一樣,並且最好在任何資料表的第一列中保留唯一鍵。然後你可以排序並連結到你心中的內容。
採用@glennjackman 映射之類的東西,您可以將映射鍵定義為北,南等
1 south somewhatPopular
2 west popular
3 north boring
4 east unexplored
在一個名為 file 的檔案中popularity
。修改fileA
為包含唯一密鑰
1 seattle 1991 west
2 atlanta 1993 west
3 turlock 1998 west
4 marysville 2004 south
5 newyork 2007 north
6 canada 2004 west
那麼您可以透過join
在選定的鍵上對這些檔案進行操作(在您的情況下,第 2 列popularity
對應到第 4 列fileA
),但join
需要在鍵欄位上對這兩個檔案進行排序,因此
join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity) | sort -k2 | awk '{print $6}'
popular
popular
popular
somewhatPopular
boring
popular
有點大錘的方法,但它給你最大的靈活性。
在每個管道上打破上述命令,您將看到每個步驟的作用。
編輯:解釋join -1 4 -2 2 # its in the man pages
這告訴join
我們查看表 1 中的第四列 (-1 4) 並在表 2 的第二列中找到匹配值 (-2 2)。
join
然後將兩個表中的列組合成單一表,但僅包含一次鍵列(北等)。查看輸出
join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity)
應該更清楚
因為我們必須對資料表進行排序才能join
工作,然後我們
| sort -k2
組合表將它們放回原來的順序。
您想要的列是組合表中的第 6 列,因此我們只需
| awk '{print $6}'
到標準輸出。
答案2
您可以嘗試將paste
兩個“表”檔案放在一起,將輸出通過管道傳輸到sort
,然後cut
僅保留第四列。
未經測試的(現在是手機)嘗試會是這樣的
paste fileA fileB | sort -s -k3,3 | cut -f4
答案3
您可以使用以下命令來取得字母映射
paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)
north boring
south popular
west someWhatPopular
然後可以使用 awk 產生所需輸出的形式:
awk '
NR==FNR {map[$1] = $2; next}
{print map[$NF]}
' <(paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)) fileA.txt
someWhatPopular
someWhatPopular
someWhatPopular
popular
boring
someWhatPopular