我有15个不同的文件,我想要一个新文件,其中只包含所有文件中的公共行。例如:
File1:
id1
id2
id3
file2:
id2
id3
id4
file3:
id10
id2
id3
file4
id100
id45
id3
id2
I need the output be like:
newfile:
id2
id3
我知道这个命令适用于每对文件:
grep -w -f file1 file2>输出
但是我需要一个命令来处理2个以上的文件。
有什么建议吗?
答案 0 :(得分:6)
Perl救援:
perl -lne 'BEGIN { $count = @ARGV }
$h{$_}{$ARGV} = 1;
}{
print $_ for grep $count == keys %{ $h{$_} }, keys %h
' file* > newfile
-n
逐行读取输入文件-l
为print
@ARGV
数组包含输入文件名,将$count
分配给BEGIN
,只计算它们$ARGV
包含当前输入文件的名称$_
包含从文件中读取的当前行。%h
哈希包含id作为键,每个键包含一个哈希引用,文件名包含id作为键}{
是"爱斯基摩人的问候"运算符,它引入了输入耗尽后运行的代码答案 1 :(得分:3)
同一个技巧可以多次使用:
$ grep -w -f file1 file2 | grep -w -f file3 | grep -w -f file4
id2
id3
顺便说一句,如果您正在寻找完全匹配,而不是正则表达式匹配,那么使用-F
标志会更好更快:
$ grep -wFf file1 file2 | grep -wFf file3 | grep -wFf file4
id2
id3
$ awk 'FNR==1{nfiles++; delete fseen} !($0 in fseen){fseen[$0]++; seen[$0]++} END{for (key in seen) if (seen[key]==nfiles) print key}' file1 file2 file3 file4
id3
id2
FNR==1{nfiles++; delete fseen}
每当我们开始阅读新文件时,我们会做两件事:(1)递增文件计数器nfiles
。 (2)删除数组fseen
。
!($0 in fseen){fseen[$0]; seen[$0]++}
如果当前行不是fseen
中的键,则将其添加到fseen
并在seen
中增加此行的计数。
END{for (key in seen) if (seen[key]==nfiles) print key}
在我们读完最后一个文件的最后一行后,我们会查看seen
中的每个键。如果该密钥的计数等于我们已读取的文件数nfiles
,那么我们将打印该密钥。
答案 2 :(得分:1)
grep -hxf file1 file2 file3 file4 |sort -u
id2
id3
# For storing it to any file,
grep -hxf file1 file2 file3 file4 |sort -u > output.txt