使用awk查找两个以上文件中常见的行

时间:2015-05-25 18:29:49

标签: linux awk

我有制表符分隔的文本文件,其中基于第1列和第2列作为键列找到它们之间的公共行。 示例文件:

file1.txt 

aba 0 0 
abc 0 1
abd 1 1 
xxx 0 0

file2.txt

xyz 0 0
aba 0 0 0 0
xxx 0 0
abc 1 1

file3.txt

xyx 0 0
aba 0 0 
aba 0 1 0
xxx 0 0 0 1
abc 1 1

我想在2个文件或3个文件中使用第1列和第2列作为搜索关键字。对于基于第1列和第2列的公共行,报告任何文件中的第一次出现都可以完成工作。

2个文件中常见行的示例输出:

abc 1 1

3个文件中常见行的示例输出:

 aba 0 0
 xxx 0 0

在实际情况中,我必须为文件数指定不同的值。任何人都可以建议一个通用的解决方案来传递它必须通用的文件数量的值。

我有这段代码可以查找所有文件中常见的行。

awk '
FNR == NR { 
    arr[$1,$2] = 1
    line[$1,$2] = line[$1,$2] ( line[$1,$2] ? SUBSEP : "" ) $0
    next
}
FNR == 1 { delete found }
{ if ( arr[$1,$2] && ! found[$1,$2] ) { arr[$1,$2]++; found[$1,$2] = 1 } }
END { 
    num_files = ARGC -1 
    for ( key in arr ) {
        if ( arr[key] < num_files ) { continue }
        split( line[ key ], line_arr, SUBSEP )
        for ( i = 1; i <= length( line_arr ); i++ ) { 
            printf "%s\n", line_arr[ i ]
        } 
    } 
}
' *.txt  > commoninall.txt

2 个答案:

答案 0 :(得分:0)

这应该有效:

cat file[123].txt | sort | awk 'BEGIN{FS="\t"; V1=""; V2=""} 
    {if (V1==$1 && V2==$2) { b=b+1 } else 
    { print b":"$0; b=1; V1=$1; V2=$2} }' |grep "2:"|awk '
    BEGIN{FS=":"} {print $2}'

我在一个流中捕获所有文件,对行进行排序,检查前两个标签分隔的列是否相等(如果它们是打印行),然后过滤掉所有重复的行。

BTW:我从William Pursell的评论中采用了这个很好的文件[123] .txt全球化的想法。

答案 1 :(得分:0)

这也应该有用

我将所有行放在一个数组(b)中,并带有两个第一个值,并以重复次数累积。如果数字> 1它将从b打印,其中为该对组合column1 / column2

保存了最后一行

div[class^="col-"]:not(:first-child) {padding-left: 2.5px;} div[class^="col-"]:not(:last-child) {padding-right: 2.5px;}

也可以吗?

修改

要显示所有文件中的所有行,您只需要多一点:

cat *.txt | awk -F" " '{a[$1$2]=a[$1$2]+1; b[$1$2]=$0} END{ for (i in a){if(a[i]>1){print b[i]}}}'

非常感谢@PeterPaulKiefer关于cat * txt的想法