shell 使用带条件的AWK合并两个文件

elcex8rz  于 2022-11-16  发布在  Shell
关注(0)|答案(3)|浏览(172)

我是新的bash脚本和需要帮助以下问题。我解析了一个日志文件,以获得以下,现在卡在后面的部分。我有一个file1.csv与内容为:

mac-test-1,10.32.9.12,15
mac-test-2,10.32.9.13,10
mac-test-3,10.32.9.14,11
mac-test-4,10.32.9.15,13

第二个file2.csv具有以下内容:

mac-test-3,10.32.9.14
mac-test-4,10.32.9.15

我想做一个文件比较,如果第二个文件中的行与第一个文件中的任何行匹配,则更改文件1的内容,如下所示:

mac-test-1,10.32.9.12, 15, no match
mac-test-2,10.32.9.13, 10, no match
mac-test-3,10.32.9.14, 11, matched
mac-test-4,10.32.9.15, 13, matched

我试过这个

awk -F "," 'NR==FNR{a[$1]; next} $1 in a {print $0",""matched"}' file2.csv file1.csv

但它将在下面打印,并且不包括不匹配的记录

mac-test-3,10.32.9.14,11,matched 
mac-test-4,10.32.9.15,13,matched

此外,在某些情况下,file2可以为空,因此结果应如下所示:

mac-test-1,10.32.9.12,15, no match
 mac-test-2,10.32.9.13,10, no match
 mac-test-3,10.32.9.14,11, no match
 mac-test-4,10.32.9.15,13, no match
p1tboqfb

p1tboqfb1#

使用您显示的示例,请尝试以下awk代码。您不需要先检查条件,然后再打印语句,因为当您检查$1 in a时,那些不存在的项将永远不会进入此条件的块中。因此,最好打印整行file1.csv,然后打印特定行的状态(匹配或不匹配)-根据数组中是否存在匹配

awk '
BEGIN  { FS=OFS="," }
FNR==NR{
  arr[$0]
  next
}
{
  print $0,(($1 OFS $2) in arr)?"Matched":"Not-matched"
}
' file2.csv file1.csv

***EDIT:***在此处添加一个解决方案来处理file2.csv场景的空文件,与上面的概念相同,只是它处理file2.csv为空文件时的场景。

awk -v lines=$(wc -l < file2.csv) '
BEGIN  { FS=OFS=","}
(lines==0){
  print $0,"Not-Matched"
  next
}
FNR==NR{
  arr[$0]
  next
}
{
  print $0,(($1 OFS $2) in arr)?"Matched":"Not-matched"
}
' file2.csv file1.csv
dwbf0jvd

dwbf0jvd2#

不打印else大小写:

awk -F "," 'NR==FNR{a[$1]; next}
{
 if ($1 in a) {
  print $0 ",matched"
 } else {
  print $0 ",no match"
 }
}' file2.csv file1.csv

输出量

mac-test-1,10.32.9.12,15,no match
mac-test-2,10.32.9.13,10,no match
mac-test-3,10.32.9.14,11,matched
mac-test-4,10.32.9.15,13,matched

或者简而言之,不用手动打印逗号,而是使用OFS:

awk 'BEGIN{FS=OFS=","} NR==FNR{a[$1];next}{ print $0 OFS (($1 in a)?"":"no")"match"}' file2.csv file1.csv

编辑

我在this page上找到了一个解决方案,在一个空文件上处理FNR==NR。
当file2.csv为空时,所有输出行将为:

mac-test-1,10.32.9.12,15,no match

范例

awk -F "," '
ARGV[1] == FILENAME{a[$1];next}
{
 if ($1 in a) {
  print $0 ",matched"
 } else {
  print $0 ",no match"
 }
}' file2.csv file1.csv
iswrvxsc

iswrvxsc3#

@RavinderSingh13和@Thefourthbird的答案都包含了解决方案的大部分内容,但在这里,它们是一个整体:

awk '
    BEGIN { FS=OFS="," }
    { key = $1 FS $2 }
    FILENAME == ARGV[1] {
        arr[key]
        next
    }
    {
        print $0, ( key in arr ? "matched" : "no match") 
    }
' file2.csv file1.csv

或者如果您愿意:

awk '
    BEGIN { FS=OFS="," }
    { key = $1 FS $2 }
    !f {
        arr[key]
        next
    }
    {
        print $0, ( key in arr ? "matched" : "no match") 
    }
' file2.csv f=1 file1.csv

相关问题