我在终端上运行以下代码。
LC_ALL=C && grep -F -f genename2.txt hg38.hgnc.bed > hg38.hgnc.goi.bed
这并没有给我两个文件之间的共同点。我在那里缺少什么?
答案1
用于comm -12 file1 file2
获取两个文件中的公共行。
您可能还需要对文件进行排序才能comm
按预期工作。
comm -12 <(sort file1) <(sort file2)
从man comm
:
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
或者使用grep
命令您需要添加-x
选项以将整行匹配为匹配模式。该F
选项告诉grep
匹配模式作为字符串而不是正则表达式匹配。
grep -Fxf file1 file2
或者使用awk
.
awk 'NR==FNR{seen[$0]=1; next} seen[$0]' file1 file2
这是阅读整行文件1到一个名为的数组中,seen
其中键是整行(在awk
中$0
表示整个当前行)。
我们用作NR==FNR
仅针对第一个输入运行以下块的条件文件1并不是文件2(NR
指的是跨记录数全部输入,FNR
是每个单独输入的文件记录数。因此,FNR
对于每个输入文件来说是唯一的,而NR
对于所有输入文件来说是唯一的。)
该next
语句告诉awk
不要继续其余的代码,而是重新开始,直到NR
不等于FNR
,这意味着所有行文件1被 阅读awk
。
那么下一个条件seen[$0]
将仅适用于第二个输入文件2。对于中的每一行文件2它将打印标记为存在的每一=1
行文件1在数组中。
另一个简单的选择是使用sort
and uniq
:
sort file1 file2|uniq -d
这将打印两个已排序的文件,然后uniq -d
仅打印重复的行。但是,当两个文件本身没有重复的行时,这是被授予的,否则即使两个文件中都有重复的行,下面的内容也始终被授予。
uniq -d <(sort <(sort -u file1) <(sort -u file2))
答案2
由于您在 Linux 上运行,我认为它是 GNU/Linux 并且您正在使用 GNUdiff
命令。
如果您正在运行 GNUdiff
命令,则可以通过以下方式查看所有已更改的行以及公共行:
diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"$@"
这与经典输出类似diff
,但输出中不会出现文件名或分隔行,旧行用 标记-
,新行用 前缀+
,公共行用空格前缀。
下面是一个示例 shell 脚本以及测试文件的结果输出:
$ cat diffcomm.sh
#!/bin/sh
diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"$@"
$ cat > filea
a
b
c
d
$ cat > fileb
a
z
d
$ ./diffcomm.sh filea fileb
a
-b
-c
+z
d
$
您可以修改每一类线的输出格式。
请参阅man diff
或info diff
或GNU diffutils 文档了解更多信息。