【发布时间】:2021-04-03 22:07:32
【问题描述】:
我的问题是很久以前提出的问题的延伸。问题是在 linux 中的 >2 个文件中找到共同元素,匹配特定列中的条目。
问题是(我指的是这个帖子:find common elements in >2 files)
我有如下三个文件
file1.txt
"aba" 0 0 1
"abc" 0 1
"abd" 1 1
"xxx" 0 0
file2.txt
"xyz" 0 0
"aba" 0 0 0 1
"xxx" 0 0
"abc" 1 1
file3.txt
"xyx" 0 0
"aba" 0 0
"xxx" 0 0 0 1
"abc" 1 1
我想根据前两列在所有三个文件中找到相似的元素。
现在,我不仅要从所有文件中找到相似的元素,还要从所有文件中打印相应的行。请注意,我的所有文件都没有排序。
注意:我希望仅从所有文件中匹配第 1 列中的元素,并按顺序打印文件中的相应行。
所以,在这个例子中,我想要的输出是:
"xxx" 0 0 0 0 0 0 1
"aba" 0 0 1 0 0 0 1 0 0
"abc" 0 1 1 1 1 1
它从文件 1-3 顺序打印匹配的元素 ($1)。
一位用户为此提供了以下解决方案:
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 ]
}
}
}
' file1.txt file2.txt file3.txt
但是,这匹配前 2 列,并且仅打印列表中第一个出现的文件(此处为 file1.txt)中的整行
这给出的输出是:
"xxx" 0 0
"aba" 0 0
"aba" 0 0 1
有没有办法修改这个脚本,以便打印所有文件中的匹配行。我需要以上述格式并排显示这些行。我的文件是制表符分隔的,因此也希望输出也以制表符分隔。另一个重要的一点是文件都包含相同的列数但不同的行数。
【问题讨论】:
-
aba 是否意味着在预期结果中出现两次?
-
实际上在我的文件中元素是独一无二的。在此示例中,aba 出现了两次,因此可能会造成混淆。如果您愿意,可以假设我正在比较前两列,并且第 1 列中的元素都是唯一的。谢谢。然而,在第二列中有重复项,但第一列优先。
-
此外,我认为没有必要比较第 2 列中的元素。由于在我的文件中,第 1 列的值都是唯一的,我可以在所有文件中匹配它们,并显示每个文件中的行包含通用元素的文件。
-
那么 abc 不应该也出现吗?
-
是的,如果我只匹配第一列,应该出现 abc。在给出的示例中,它匹配前两列,因此 abc 不会出现。我有兴趣匹配第 1 列。我将在原始帖子中进行必要的编辑。