bash比较两个不同长度的文件中的多列

use*_*334 3 bash awk text-processing

我在文本文件中有以下数据集

数据.txt

d1,40,gold
d2,30,silver
d3,20,bronze
d4,10,iron
d5,5,wood
d6,20,gold
d7,10,wood
d8,5,gold
d9,10,silver
 .
 .
 .
Run Code Online (Sandbox Code Playgroud)

定义文件

gold,40
silver,30
bronze,20
iron,10
wood,5
Run Code Online (Sandbox Code Playgroud)

我需要的是将数据与我的定义文件进行比较,并在主文件中添加状态为“ok”或“nok”。由于数据文件很大,我可以用while循环找出来,但需要很长时间。有没有优化的方法?

数据.txt

d1,40,gold,ok
d2,30,silver,ok
d3,20,bronze,ok
d4,10,iron,ok
d5,5,wood,ok
d6,20,gold,nok
d7,10,wood,nok
d8,5,gold,nok
d9,10,silver,nok
Run Code Online (Sandbox Code Playgroud)

αғs*_*нιη 5

通过单个命令,我认为它会比使用 while 循环更快。您可以通过time命令前面的命令测试它的速度,看看它是否很快;)

awk -F, 'NR==FNR{ arr[$2]=$2 $1; next } 
    { print $0, (arr[$2]==$2 $3?"ok":"nok") }' OFS=, def.txt data.txt
d1,40,gold,ok
d2,30,silver,ok
d3,20,bronze,ok
d4,10,iron,ok
d5,5,wood,ok
d6,20,gold,nok
d7,10,wood,nok
d8,5,gold,nok
d9,10,silver,nok
Run Code Online (Sandbox Code Playgroud)

解释:

  • NRawk读取第一条记录时设置为 1,并为每个下一个读取单个或多个输入文件的记录递增,直到所有读取完成。

  • FNRawk读取第一条记录时设置为 1,并为当前文件中读取的每个下一个记录递增,如果有多个输入文件,则为下一个输入文件重置回 1。

  • 所以NR == FNR对于第一档真正只def.txt

  • arr[$2]=$2 $1; 创建一个以arr键命名的关联数组,$2并复制第二个和第一个字段作为其值。

  • 所述next令牌跳到执行的命令的休息和那些只用于除了第一下一个文件(一个或多个)实际执行。

  • 这将print $0打印整行data.txt并且(arr[$2]==$2 $3?"ok":"nok")(称为三元运算符 ( condition?"if-true":"if-false") 检查键值 inarr[$2]是否与data.txt 中$2 $3(第二和第三个字段)的值相等,然后打印"ok" else "nok"

  • 如果您的 data.txt 文件和 def.txt 文件不是sort-ed ,这也将起作用。