我想使用Linux命令或脚本比较两个文件中的数据。第一个文件由一系列的7个数字组成,后接一行的名称,文件中包含多行数字和名称。数字不能在同一行上重复,但可以在另一行上找到,并且将按顺序在每行上列出。
File1示例:
01 02 03 04 05 06 07 Name1
11 12 13 14 15 16 17 Name2
01 03 05 11 12 14 16 Name3
...
我想知道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 Name3
如果没有匹配项,我想显示" No Match"或类似内容。
我是Linux和脚本文件的新手,感谢您提供的所有帮助。谢谢。
只是澄清一下,您是否希望文件2中的一行与文件1相匹配,只要所有数字都出现在文件2中该行的某个点上?
如果File2仅一行?
使用Awk相当容易。让我们来看看这个零碎的东西。
NR==FNR { for (i=1; i<=NF; ++i) a[$i]=1; next }
当我们读取第一个输入文件时,NR==FNR条件为true。我们遍历输入字段,并为每个数组分配关联数组a中的键。现在,它包含第一个文件的输入字段(运行时将确保它是File2)。
在另一个文件的行上,将字段循环到倒数第二个字段(我们跳过最后一个包含标识符的字段,例如Name2)。如果a中没有任何值,请放弃此行。
{ for (i=1; i
否则,请打印。
1
(孤独的1是Awk惯用语,如果我们进入脚本的这一部分,它将打印输入。这是一个很简单的情况,没有任何动作;默认动作是打印输入行。)
我们将所有内容收集到一个shell脚本代码片段中,
awk 'NR==FNR { for (i=1; i<=NF; ++i) a[$i] = 1; next }
{ for (i=1; i
假定File2仅包含一行。如果要扩展到多行,Awk的功能会有些紧张。在那时,也许考虑切换到Perl或Python(或您碰巧熟悉的其他任何东西)。 Awk的吸引力在于它很简单-您可以在一天内学习它,并在一周内编写好的脚本。
美丽! 比普通的Bash好得多=)
完善! 这是使我的程序正常运行的关键最终组成部分。 我还有很多事情要学习,我将Awk添加到列表的顶部。 @savanto也感谢您的帮助。 我同意,这样效果更好。 我很感激。 谢谢。
这个(相当丑陋的)bash脚本将在给定的样本数据上产生正确的结果:
# Read numbers against which to match from File2 into array.
read -a match_array <<
# 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