在shell中合并bash中的两个文件

时间:2016-06-22 23:58:16

标签: linux shell

以下问题有些棘手,但看似简单,我需要使用bash

让我们假设我有2个文本文件,第一个是

FirstFile.txt

0 1
0 2
1 1
1 2
2 0

SecondFile.txt

0 1
0 2
0 3
0 4
0 5
1 0
1 1
1 2 
1 3
1 4
1 5
2 1 
2 2 
2 3
2 4 
2 5

我希望能够创建一个新的Thirdfile.txt,其中包含不在文件A中的值,这意味着如果文件A中有一个公共变量,我希望将其删除。知道2 0和0 2是相同的......

你可以帮帮我吗?

2 个答案:

答案 0 :(得分:0)

使用awk,您可以重新排列列,以便较低的数字始终位于第一位。读取第一个文件时,将它们保存为关联数组中的键。读取第二个文件时,请测试它们是否在阵列中找不到。

awk '{if ($1 <= $2) { a = $1; b = $2; } else { a = $2; b = $1 } }
     FNR==NR { arr[a, b] = 1; next; }
     !arr[a, b]' FirstFile.txt SecondFile.txt > ThirdFile.txt

结果:

0 3
0 4
0 5
1 3
1 4
1 5
2 2 
2 3
2 4 
2 5

答案 1 :(得分:0)

paste <(cut -f2 a.txt) <(cut -f1 a.txt) > tmp.txt
cat a.txt b.txt tmp.txt | sort | uniq -u

cat a.txt b.txt <(paste <(cut -f2 a.txt) <(cut -f1 a.txt)) | sort | uniq -u

<强>结果

0   3
0   4
0   5
1   3
1   4
1   5
2   2
2   3
2   4
2   5

<强>解释

uniq从文本文件中删除重复的行。

uniq要求对其输入进行排序。

uniq -u仅打印没有重复项的行。

所以,cat a.txt b.txt | sort | uniq -u几乎可以让你到达:只有b.txt中不在a.txt中的行才会打印出来。然而,它没有处理相反的情况,例如'1 2'&lt; - &gt; '2 1'。

因此,您需要一个包含所有反向删除键的临时文件。这就是paste <(cut -f2 a.txt) <(cut -f1 a.txt)所做的。

请注意,cut假定列以\ t分隔。如果不是,则需要指定分隔符,例如-d ' '