解释:

解释:

您好,我有两个文件,它们的文件名如下所示:

文件 1:

123.txt
456.txt
789.txt
101112.txt

文件 2:

123.txt 
789.txt
101112.txt

是否有任何 bash 命令可用于重叠它们并仅打印不匹配的行或文件名。所以我期望类似这样的结果:

456.txt

答案1

comm你的朋友在这里吗:

如果文件已经排序:

comm -3 f1.txt f2.txt

如果未排序,sort则使用进程替换将它们作为文件描述符传递(这样我们就不需要任何临时文件):

comm -3 <(sort f1.txt) <(sort f2.txt)

例子:

% cat f1.txt
123.txt
456.txt
789.txt
101112.txt

% cat f2.txt
123.txt
789.txt
101112.txt

% comm -3 <(sort f1.txt) <(sort f2.txt)
456.txt

答案2

一种简单的方法是使用两个“grep”命令,每个命令将其中一个文件作为行列表来搜索另一个文件。假设您的文件名为 f1.txt 和 f2.txt:

grep -Fxvf f1.txt f2.txt ; grep -xvf f2.txt f1.txt

使用的选项grep如下:

  • -F- 使用每一行作为固定字符串进行匹配,而不是正则表达式
  • -x- 仅匹配整行
  • -v- 反转匹配以选择不匹配的行
  • -f- 使用作为参数给出的文件作为要匹配的模式列表

答案3

我理解你的问题是,你想要所有行只出现在其中一个文件中,而不是两个文件中,并且忽略行顺序。

我还假设我们比较文件f1.txtf2.txt。插入你们各自的名字。

使用 Bash,你可以用两个循环来实现,每个循环处理一个文件并检查每一行是否出现在另一个文件中。这种方法效率不高,但应该可以工作:

# This loops over f1.txt and searches each line in f2.txt
while read line ; do grep -Fxqe "$line" f2.txt || echo "$line" ; done < f1.txt 

# This loops over f2.txt and searches each line in f1.txt
while read line ; do grep -Fxqe "$line" f1.txt || echo "$line" ; done < f2.txt 

两个循环一起产生所需的结果。每个循环本身仅检查一个文件中没有出现在另一个文件中的行。

可以使用例如简短的 Python 单行代码来编写更简洁的解决方案:

python3 -c 's1=set(open("f1.txt")); s2=set(open("f2.txt")); print(*s1.symmetric_difference(s2), sep="")'

这使用了一个集合数据结构,它只包含唯一值并允许像“对称差异”这样的集合操作。

请注意,使用这两种解决方案时,如果任何文件包含重复的行,这些行将被忽略并仅作为单个事件处理。

答案4

假设您不需要结果保持原始顺序,只需使用:

cat file1 file2 | sort | uniq -u

解释:

cat file1 file2

将两个文件依次输出到标准输出。

sort

对两个文件的组合内容进行排序。我们感兴趣的有用的副作用是,这会将两个文件中相同的行放在一起。

uniq -u

仅输出“唯一”的行,即仅出现一次的行。令人讨厌的是,它只查看相邻的行对,这就是为什么前一个sort命令是必要的。

您还可以使用uniq -d仅输出出现两次的行。这将为您提供两个文件共有的行。

笔记:如果相同的行在同一个文件中出现多次,我不确定这个解决方案的效果如何。

相关内容