如何解决从多个文本文件中提取公共行并显示原始行号
我想要什么?
- 从n个大文件中提取公用行。
- 附加每个文件的原始行号。
示例:
File1.txt具有以下内容
apple
banana
cat
File2.txt具有以下内容
boy
girl
banana
apple
File3.txt具有以下内容
foo
apple
bar
输出应为其他文件
1 3 2 apple
输出中的1、3和2是File1.txt
,File2.txt
和File3.txt
的原始行号,其中存在公共行apple
我尝试使用grep -nf File1.txt File2.txt File3.txt
,但返回
File2.txt:3:apple
File3.txt:2:apple
解决方法
将每个唯一行与一个用空格隔开的行号列表相关联,以指示在数组中每个文件中的位置,如果在所有三个文件中都找到该行,则将它们相邻显示在末尾。
awk '{
n[$0] = n[$0] FNR OFS
c[$0]++
}
END {
for (r in c)
if (c[r] == 3)
print n[r] r
}' file1 file2 file3
如果文件数未知,请参考Ravinder's answer,或使用 ARGC-1更改 END 块中的硬编码 3 (如此处所示)。
,适用于任意数量文件的GNU awk特定方法:
#!/usr/bin/gawk -f
BEGINFILE {
nfiles++
}
{
lines[$0][nfiles] = FNR
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
for (line in lines) {
if (length(lines[line]) == nfiles) {
for (file = 1; file <= nfiles; file++)
printf "%d\t",lines[line][file]
print line
}
}
}
示例:
$ ./showlines file[123].txt
1 3 2 apple
,
请问您可以尝试使用GNU awk
进行后续的编写和测试,可以利用ARGC
的值来获取传递给awk
程序的元素总数。
awk '
{
a[$0]=(a[$0]?a[$0] OFS:"")FNR
count[$0]++
}
END{
for(i in count){
if(count[i]==(ARGC-1)){
print i,a[i]
}
}
}
' file1.txt file2.txt file3.txt
,
Perl解决方案
perl -ne '
$h{$_} .= "$.\t"; # append current line number and tab character to value in a hash with key current line
$. = 0 if eof; # reset line number when end of file is reached
END{
while ( ($k,$v) = each %h ) { # loop over has entries
if ( $v =~ y/\t// == 3 ) { # if value contains 3 tabs
print $v.$k # print value concatenated with key
}
}
}' file1.txt file2.txt file3.txt
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。