我有 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 文件 1 文件 2 > 输出
但我需要一个命令来处理超过 2 个文件。
请问有什么建议吗?
Perl 的救援:
perl -lne 'BEGIN { $count = @ARGV }
$h{$_}{$ARGV} = 1;
}{
print $_ for grep $count == keys %{ $h{$_} }, keys %h
' file* > newfile
-n逐行读取输入文件-l添加换行符print@ARGV数组包含输入文件名,将其分配给$countningBEGIN只是计算它们$ARGV包含当前输入文件的名称$_包含从文件中读取的当前行。%h包含包含 id 作为键的文件名}{是“Eskimo greeting”操作符,它引入了在输入用完后运行的代码可以多次使用相同的技巧:
$ 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]++}
如果当前行不是 in 中的键fseen,则将其添加到in 中fseen并增加该行的计数seen。
END{for (key in seen) if (seen[key]==nfiles) print key}
在我们读完最后一个文件的最后一行之后,我们查看seen. 如果该键的计数等于我们已读取的文件数nfiles,则我们打印该键。
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