如何在Linux中对具有大量数据的文件进行排序和连接,并为未找到的值打印空白值

如何在Linux中对具有大量数据的文件进行排序和连接,并为未找到的值打印空白值

考虑以下文件:

文件1:

1

2

3

4

文件2:

2

3

6

9

预期输出:

1 NULL

2 2

3 3

4 NULL

NULL 6

NULL 9

我已经尝试过了paste file1 file2 | sed 's/\t/\0\t/g' | column -s $'\t' -t,它并没有给我带来预期的效果。

答案1

命令 comm 可以以接近您要求的格式为您提供所需的结果。在我的系统中,默认安装了 comm (GNU coreutils) 8.25。我创建了两个文件 b 和 c txt,其中包括您的数据以及更多用于测试的数字。

comm --nocheck-order b.txt c.txt #(or file1.txt file2.txt)

输出 :

1
                2
                3
4
        6
8
                9
        10
        11
                13
                16
        17
18
                19
20
22

第一列包含文件 1 中与文件 2 不匹配的条目。

第二列表示文件 2 中与文件 1 不匹配的条目。

第三列表示文件 1 和 2 中常见/匹配的条目

尽管您的文件已排序,但出于某种原因,comm 会抱怨未排序的文件。可以使用 --nocheck-order 开关来解决。

该列表可以使用自定义分隔符进行格式化(请参阅 man comm)。

既然您已经构建了列表,您可以像这样操作它:

readarray data < <(comm --nocheck-order --output-delimiter "-"  b.txt c.txt)
for ((i=0;i<${#data[@]};i++)); do
va=$(grep -e "-" <<<"${data[$i]}")
if [[ $va == "" ]]; then
    echo ${data[$i]} " null"
elif [[ $va == "--"* ]]; then 
        data2=$(echo ${data[$i]} | grep -Po '[0-9]*')
        echo $data2 " " $data2
else
    data2=$(echo ${data[$i]} | grep -Po '[0-9]*')
    echo "null " $data2
fi
done

其他有趣的命令是 join 和 sdiff,但 comm 是最接近的。您也可以看看这篇文章: https://askubuntu.com/questions/515900/how-to-compare-two-files

问候

相关内容