Shell脚本比较具有多行模式的文件

时间:2018-08-29 11:06:44

标签: bash shell

我有一个在手动配置后创建的文件。 我需要使用Shell脚本自动检查此文件。 该文件如下所示:

eth0;eth0;1c:98:ec:2a:1a:4c
eth1;eth1;1c:98:ec:2a:1a:4d
eth2;eth2;1c:98:ec:2a:1a:4e
eth3;eth3;1c:98:ec:2a:1a:4f
eth4;eth4;48:df:37:58:da:44
eth5;eth5;48:df:37:58:da:45
eth6;eth6;48:df:37:58:da:46
eth7;eth7;48:df:37:58:da:47

我想将其与这样的模式进行比较:

eth0;eth0;*
eth1;eth1;*
eth2;eth2;*
eth3;eth3;*
eth4;eth4;*
eth5;eth5;*
eth6;eth6;*
eth7;eth7;*

如果只需要检查此模式,就可以运行此循环:

c=0
while [ $c -le 7 ]
do
    if [ "$(grep "eth"${c}";eth"${c}";*" current_mapping)" ]; 
    then
        echo "eth$c ok" 

fi 
    (( c++ ))
done

可能有6种或更多不同的模式。例如,模式也可能看起来像这样(取决于具体的配置请求):

eth4;eth0;*
eth5;eth1;*
eth6;eth2;*
eth7;eth3;*
eth0;eth4;*
eth1;eth5;*
eth2;eth6;*
eth3;eth7;*

因此,我认为我无法在循环中每行命令运行标准grep。 eth编号不一致。

是否可能以某种方式将整个文件与模式进行比较,就像使用grep进行单行处理一样?

3 个答案:

答案 0 :(得分:0)

假设file是您的数据文件,而patt是包含上述模式的文件。您可以将此grep -fsed结合使用,以进行流程替换,将*替换为.*,将?替换为.,使其成为可行的正则表达式。

grep -f <(sed 's/\*/.*/g; s/?/./g' patt) file

eth0;eth0;1c:98:ec:2a:1a:4c
eth1;eth1;1c:98:ec:2a:1a:4d
eth2;eth2;1c:98:ec:2a:1a:4e
eth3;eth3;1c:98:ec:2a:1a:4f
eth4;eth4;48:df:37:58:da:44
eth5;eth5;48:df:37:58:da:45
eth6;eth6;48:df:37:58:da:46
eth7;eth7;48:df:37:58:da:47

答案 1 :(得分:0)

尝试任何方法:

grep -P '(eth[0-9]);\1'
grep -E '(eth[0-9]);\1'
sed -n '/\(eth[0-9]\);\1/p'
awk -F';' '$1 == $2'

仅存在命令。将它们应用于管道或文件。

问题编辑后更新了答案。

我们可以看到任务要求如下:

  • 格式为ethN;ethM;MAC的文件(一组行)
  • 检查每一行是否相等ethNethM
  • 如果它们相等,则输出字符串ethN ok

如果我对任务的理解正确,我们可以使用以下代码无循环来实现:

awk -F';' '$1 == $2 { print $1, "ok" }'

答案 2 :(得分:0)

我现在写了这个循环,它完成了工作(current_mapping是问题的第一个代码块中包含内容的文件)。我将不得不创建具有不同模式的数组,并为每个模式使用一个案例。我只是想知道是否有类似grep的多行代码,在不编写此循环的情况下是否可能相同?

array=("eth0;eth0;*" "eth1;eth1;*" "eth2;eth2;*" "eth3;eth3;*" "eth4;eth4;*" "eth5;eth5;*" "eth6;eth6;*" "eth7;eth7;*")

c=1
while [ $c -le 8 ]
do

if [ ! "$(sed -n "${c}"p current_mapping | grep "${array[$c-1]}")" ]; 
then
echo "somethings wrong" 

fi 
(( c++ ))
done