Bash 更改匹配变量行中的第一个字

Bash 更改匹配变量行中的第一个字,bash,Bash,我想不出合适的标题,所以如果我想要的与标题不匹配,请原谅 我有一个配置,它有来自Cisco设备的接口统计输出。然后,我的脚本遍历并解析数据行并将其分离,以便将某些项目导出到CSV。脚本在运行到ATM端口之前对所有其他端口都非常有效。我试图解析的问题数据如下所示: ATM0/0/0 is up, protocol is up line 1 line 2 line 3 line 4 ATM0/0/0.1 is up, protocol is up line 1 line 2 ATM0/0/0.2 i

我想不出合适的标题,所以如果我想要的与标题不匹配,请原谅

我有一个配置,它有来自Cisco设备的接口统计输出。然后,我的脚本遍历并解析数据行并将其分离,以便将某些项目导出到CSV。脚本在运行到ATM端口之前对所有其他端口都非常有效。我试图解析的问题数据如下所示:

ATM0/0/0 is up, protocol is up
line 1
line 2
line 3
line 4
ATM0/0/0.1 is up, protocol is up
line 1
line 2
ATM0/0/0.2 is up, protocol is up
line 1
line 2
if cat $cfg | grep "ATM0/[0-3]/0.[0-3]" ; then
sed -i 's/ATM/SUB_VAR/'
fi
 ATM0/0/0.1 is up, protocol is up line 1 line 2
 ATM0/0/0.2 is up, protocol is up line 1 line 2
 ATM0/1/0.1 is up, protocol is up line 1 line 2
 ATM0/1/0.2 is up, protocol is up line 1 line 2
我用来解析信息的脚本如下所示:

cfg=./config.text
inter=$(cat $cfg | grep "protocol is" | awk '{print $1}')

for i in $inter
do
if [[ $i == ATM0/*/0.* ]] ; then
cat $cfg | grep -A2 "$i" | sed -e 's/--//g' -e '/^\s*$/d' | paste -d " " - - - > tmp
    grep "$i" ./tmp | while read -r line ; do
            sts1=$(echo $line | awk '{print $3}' | sed 's/,//g')
            sts2=$(echo $line | awk '{print $6}')
            sts3=$(echo $line | awk '{print $8}')
            sts4=$(echo $line | awk '{print $10}')
    echo "$hostname, $ip, $i, $sts1, $sts2, $sts3, $sts4, NA, NA, NA, NA, NA" >> Details.csv
    done
elif [[ $i == ATM0/*/0 ]] ; then
           similar coding as above
   echo "$var, $var, $var" >> Details.csv
done
fi
done
问题是,由于主ATM和子ATM端口都以ATM开头,因此我的grep命令无法区分这两个端口。因此,它将在匹配“ATM0/*/0”后拾取接下来的4行

我尝试使用sed将子ATM端口从ATM更改为唯一的名称,以便它能够通过数据处理。我使用的代码如下:

ATM0/0/0 is up, protocol is up
line 1
line 2
line 3
line 4
ATM0/0/0.1 is up, protocol is up
line 1
line 2
ATM0/0/0.2 is up, protocol is up
line 1
line 2
if cat $cfg | grep "ATM0/[0-3]/0.[0-3]" ; then
sed -i 's/ATM/SUB_VAR/'
fi
 ATM0/0/0.1 is up, protocol is up line 1 line 2
 ATM0/0/0.2 is up, protocol is up line 1 line 2
 ATM0/1/0.1 is up, protocol is up line 1 line 2
 ATM0/1/0.2 is up, protocol is up line 1 line 2
不幸的是,这将所有ATM实例都变成了SUB_VAR。我不确定如何处理这个问题,并寻求如何实现这一点的指导

更新: 每个IF语句都应该匹配第一个模式,然后在该模式之后获取一组行,并将其放入tmp文件中。从这里开始,它对每个匹配的模式进行格式化,放入一行,如下所示:

ATM0/0/0 is up, protocol is up
line 1
line 2
line 3
line 4
ATM0/0/0.1 is up, protocol is up
line 1
line 2
ATM0/0/0.2 is up, protocol is up
line 1
line 2
if cat $cfg | grep "ATM0/[0-3]/0.[0-3]" ; then
sed -i 's/ATM/SUB_VAR/'
fi
 ATM0/0/0.1 is up, protocol is up line 1 line 2
 ATM0/0/0.2 is up, protocol is up line 1 line 2
 ATM0/1/0.1 is up, protocol is up line 1 line 2
 ATM0/1/0.2 is up, protocol is up line 1 line 2
从这里,我可以使用awk解析我想要的信息。问题是ATM端口的模式匹配同时捕获ATM和ATM子端口。从那里,tmp文件的错误输出如下所示:

ATM0/1/0 is up, protocol is up line 1 line 2 line 3 line 4
ATM0/1/0.1 is up, protocol is up line 1 line 2 ATM0/1/0.2 is up, protocol is up line 1
line 2 FastEthernet0/1 is up, protocol is up line 1
正如您所看到的,它对子端口很好,但正如您所看到的,对于常规端口,它不应该是一种抓取,我确信这是因为我在IF语句中使用的模式。

这有帮助吗

sed -r "s/ATM0(\/[0-3]+\/0[^.].*)/atm0\1/" atm.log 

atm0/0/0 is up, protocol is up
line 1
line 2
line 3
line 4
ATM0/0/0.1 is up, protocol is up
line 1
line 2
ATM0/0/0.2 is up, protocol is up
line 1
line 2
方括号中的点与文字点匹配。前面的插入符号否定它

使用-i,您可以在适当的位置更改文件

sed -r -i "s/ATM0(\/[0-3]+\/0[^.].*)/atm0\1/" atm.log 
改变相反的方式:

sed -r "s/ATM0(\/[0-3]+\/0[.].*)/atm0\1/" atm.log 

ATM0/0/0 is up, protocol is up
line 1
line 2
line 3
line 4
atm0/0/0.1 is up, protocol is up
line 1
line 2
atm0/0/0.2 is up, protocol is up
line 1
line 2

我猜小写的atm可能不会与其他名称冲突,但可以很好地指示/记录原始条目是什么。

预期输出是什么?很可能您的完整脚本可以替换为一个
awk
脚本,但反向工程所需的输出是一个挑战。如果您发布具有代表性的示例输入和预期输出,您可以获得更多帮助。@JamesBrown更新了原始问题。这正是我所希望的!再次感谢你!