使用Linux命令或脚本,我想比较两个文件中的数据。第一个文件有一系列7个数字,后跟一行上的名称,文件中有几行数字和名称。这些数字不能在同一行重复,但可以在另一行中找到,并且将按顺序列在每一行。
File1示例:
01 02 03 04 05 06 07姓名1
11 12 13 14 15 16 17姓名2
01 03 05 11 12 14 16姓名3
...
我想知道File1中的一行数字与File2中的另一组数字相匹配。 File2中的数字不重复,将按顺序排序。
File2示例:
01 02 03 04 05 11 12 13 14 15 16 18 20
只要File1中的一行数字与File2中的任何数字匹配,我希望显示匹配的行,包括名称。
输出示例:
01 03 05 11 12 14 16姓名3
如果没有匹配,我想显示“No Match”或类似内容。
我是Linux和脚本文件的新手,并感谢所有帮助。谢谢。
答案 0 :(得分:1)
使用Awk这很容易。让我们把这个零碎。
NR==FNR { for (i=1; i<=NF; ++i) a[$i]=1; next }
当我们读取第一个输入文件时,NR==FNR
条件为真。我们遍历输入字段,并在关联数组a
中为每个字段分配一个键。现在包含第一个文件的输入字段(运行时我们将确保File2
)。
在另一个文件的行上,循环遍历最后一个字段(我们跳过最后一个字段,其中包含标识符,如Name2
)。如果任何值不在a
中,请放弃此行。
{ for (i=1; i<NF; i++) if (! ($i in a)) next }
否则,请打印。
1
(孤独的1
是一个awk习语,如果我们在脚本中落到这个部分,它会打印输入。这是一个平常为真的条件,没有动作;默认动作是打印输入线。)
在shell脚本片段中收集所有内容,我们获取
awk 'NR==FNR { for (i=1; i<=NF; ++i) a[$i] = 1; next }
{ for (i=1; i<NF; i++) if (! ($i in a)) next } 1' File2 File1
这假设File2
只包含一行。如果你想扩展到多行,Awk的功能会有点紧张;在这一点上,也许可以考虑切换到Perl或Python(或者你熟悉的其他任何东西)。 Awk的吸引力在于它很简单 - 您可以在一天内学习它,并在一周内编写好的脚本。
答案 1 :(得分:0)
这个(相当难看的)bash脚本将在给定的样本数据上生成正确的结果:
# Read numbers against which to match from File2 into array.
read -a match_array <<< "$(cat File2)"
# Traverse each line in File1
while read -a line
do
if [ "$line" != "" ]
then
# Counter for the number of matches
match=0
# Strip off the name on the end, leaving only numbers to match
for n in "${line[@]:0:7}"
do
for m in "${match_array[@]}"
do
if [ "$n" == "$m" ]
then
# Successfully matched a number, increment counter.
match=$(($match + 1))
fi
done
# Correct number of matches
if [ "$match" == "7" ]
then
echo ${line[@]}
fi
done
fi
done < File1