我有以下文件:
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