paw*_*ana 9 command-line awk text-processing
File1.txt
item1 carA
item2 carB
item3 carC
item4 platD
item5 carE
Run Code Online (Sandbox Code Playgroud)
File2.txt
carA platA
carB platB
carC platC
carE platE
Run Code Online (Sandbox Code Playgroud)
想要的输出:
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
Yar*_*ron 11
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($2 in dict) ? dict[$2] : $2}1' file2.txt file1.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Run Code Online (Sandbox Code Playgroud)
这个想法是创建一个带有索引的哈希映射,并将其用作字典。
对于您在评论中提出的第二个问题(如果第二列file1.txt将是第六列,应该更改什么):
如果输入文件类似于file1b.txt:
item1 A5 B C D carA
item2 A4 1 2 3 carB
item3 A3 2 3 4 carC
item4 A2 4 5 6 platD
item5 A1 7 8 9 carE
Run Code Online (Sandbox Code Playgroud)
以下命令将执行此操作:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($6 in dict) ? dict[$6] : $6;$3="";$4="";$5="";$6=""}1' file2.txt file1b.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Run Code Online (Sandbox Code Playgroud)
我知道你说过awk,但有一个join用于此目的的命令......
{
join -o 1.1,2.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
join -v 1 -o 1.1,1.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
} | sort -k 1
Run Code Online (Sandbox Code Playgroud)
join如果不是这一行,第一个命令就足够了:
item4 platD
Run Code Online (Sandbox Code Playgroud)
该命令基本上说:基于第一个文件的第二列(-1 2)和第二个文件的第一列(-2 1)连接,并输出第一个文件的第一列和第二个文件的第二列(-o 1.1,2.2)。那只显示配对的线。第二个 join 命令说的几乎相同,但它表示显示第一个文件中无法配对的行 ( -v 1) ,并输出第一个文件的第一列和第一个文件的第二列 ( -o 1.1,1.2)。然后我们对两者的输出进行排序。sort -k 1表示基于第一列sort -k 2排序,表示基于第二列排序。在将文件传递给join.
现在,我写了两次排序,因为如果可以的话,我不喜欢在我的目录中乱扔文件。但是,就像 David Foerster 所说的那样,根据文件的大小,您可能希望对文件进行排序并首先保存它们,而不必等待对每个文件进行两次排序。为了给出大小的概念,以下是在我的计算机上对 100 万行和 1000 万行进行排序所需的时间:
$ ruby -e '(1..1000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 1million.txt
$ ruby -e '(1..10000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 10million.txt
$ head 10million.txt
item530284 plat530284
item7946579 plat7946579
item1521735 plat1521735
item9762844 plat9762844
item2289811 plat2289811
item6878181 plat6878181
item7957075 plat7957075
item2527811 plat2527811
item5940907 plat5940907
item3289494 plat3289494
$ TIMEFORMAT=%E
$ time sort 1million.txt >/dev/null
1.547
$ time sort 10million.txt >/dev/null
19.187
Run Code Online (Sandbox Code Playgroud)
100 万行需要 1.5 秒,1000 万行需要 19 秒。