在 unix 中比较并打印不匹配的字符串

Compare and print unmatched string in unix

我有类似

的文件
123|3a|3b
747|3a|3b|3c|3d
636|3c|3b

输出:

123 -3c 3d
636 -3a 3d 

它应该比较 3a,3b,3c,3d 并显示缺少的一个。

我试过使用

awk '/3a/3b/3c/3d' file.txt

但不知道如何比较单个字符串。

这个 awk 解决方案应该可以胜任

awk -F\| 'BEGIN{OFS=" "}{str=""
           str=sub("3a",[=10=]) ? str : str"3a"
           str=sub("3b",[=10=]) ? str : str"3b"
           str=sub("3c",[=10=]) ? str : str"3c"
           str=sub("3d",[=10=]) ? str : str"3d"
           if(str != ""){gsub(/[abdc]/,"& ",str)
           [=10=]=" -"str
           print [=10=]}}' test

限制:第一列不得包含 "a"、"b"、"c" 或 "d"。

输出:

123 -3c 3d 
636 -3a 3d 

如果不需要“-”,则更可靠:

awk -F\| '{str=""
           str=sub("3a",[=12=]) ? str : str"3a"
           str=sub("3b",[=12=]) ? str : str"3b"
           str=sub("3c",[=12=]) ? str : str"3c"
           str=sub("3d",[=12=]) ? str : str"3d"
           if(str != ""){gsub("3"," 3",str)
                         print ""str}}' test

输出:

123 3c 3d
636 3a 3d
$ cat list
3a,3b,3c,3d
$
$ cat file
123|3a|3b
747|3a|3b|3c|3d
636|3c|3b
$
$ cat tst.awk
NR==FNR {
    for (i=1; i<=NF; i++) {
        reqd[++numReqd] = $i
    }
    next
}
{
    c=0
    for (i=1; i<= numReqd; i++) {
        if ( [=10=] !~ "[|]" reqd[i] "([|]|$)" ) {
            printf "%s%s%s%s", (++c>1?"":), OFS, (c>1?"":"-"), reqd[i]
        }
    }
    if (c) {
        print ""
    }
}
$
$ awk -f tst.awk FS=',' list FS='|' file
123 -3c 3d
636 -3a 3d