使用Bash跳过文件中的第一个匹配项

时间:2019-01-11 11:36:35

标签: linux bash shell

我有这个文件包含此类数据

NAME: "Chassis", DESCR: "Nexus5020 Chassis"
PID: N5K-C5020P-BF     , VID: V04 , SN: SS613390FZT

NAME: "Module 1", DESCR: "40x10GE/Supervisor"
PID: N5K-C5020P-BF     , VID: V04 , SN: JA91344BHNK

NAME: "Module 2", DESCR: "6x10GE Ethernet Module"
PID: N5K-M1600         , VID: V01 , SN: JA71228018M

NAME: "Module 3", DESCR: "8x1/2/4G FC Module"
PID: N5K-M1008         , VID: V01 , SN: JAB1531020C

通过使用shell脚本,我设法获取了DESCR:和SN:中字符串形式的相关数据,并将其保存在csv文件中,如下所示;

Nexus5020 Chassis,SS613390FZT
40x10GE/Supervisor,JA91344BHNK
6x10GE Ethernet Module,JA71228018M
8x1/2/4G FC Module,JAB1531020C

我的问题是需要进行哪些修改,以便脚本将跳过DESCR:和SN:的第一个匹配项,因此输出结果将是这样?

40x10GE/Supervisor,JA91344BHNK
6x10GE Ethernet Module,JA71228018M
8x1/2/4G FC Module,JAB1531020C

脚本在这里:

#/bin/bash

re_descr='DESCR: "([^"]+)"'
re_sn='SN: ([^[:space:]]+)'

while read -r; do
        if [[ $REPLY =~ $re_descr ]]; then
                descr=${BASH_REMATCH[1]}
                continue
        fi
        if [[ $REPLY =~ $re_sn ]]; then
                sn=${BASH_REMATCH[1]}
        fi
        if [[ $descr && $sn ]]; then
                printf '%s\t%s\n' "$descr","$sn"
                unset -v descr sn
        fi
done < <(cat <filename>)

3 个答案:

答案 0 :(得分:1)

您可以将done < <(cat <filename>)替换为done < <filename> | sed 1d

它看起来像这样(,其中/tmp/foo作为输入文件):

#/bin/bash

re_descr='DESCR: "([^"]+)"'
re_sn='SN: ([^[:space:]]+)'

while read -r; do
        if [[ $REPLY =~ $re_descr ]]; then
                descr=${BASH_REMATCH[1]}
                continue
        fi
        if [[ $REPLY =~ $re_sn ]]; then
                sn=${BASH_REMATCH[1]}
        fi
        if [[ $descr && $sn ]]; then
                printf '%s\t%s\n' "$descr","$sn"
                unset -v descr sn
        fi
done < /tmp/foo | sed 1d

答案 1 :(得分:0)

不是将输入从末尾传递到while循环,而是将输入作为内部循环传递。

尝试此操作以删除多个输入文件的第一行

$ cat in.txt
line1
line2
line3
line4
$ perl -ne ' { print if $.>1 ; close(ARGV) if eof } ' in.txt in.txt | while read -r a ; do ; echo $a  ; done
line2
line3
line4
line2
line3
line4
$

我只是使用in.txt in.txt来表明它删除了第一行。

答案 2 :(得分:0)

您可以添加变量firstline(将其初始化为true)。 当sndescr匹配时,将变量设置为false,否则打印。

编辑:替代。

您可以使用tr和sed操作文件。
首先,请确保所有行(第一行除外)均以DESCR开头:

tr -d "\n" < file | sed 's/DESCR/\n&/g; $ s/$/\n/'

第一行没有DESCR,第二行是您要忽略的那一行。
因此,请从第三行处理此流:

tr -d "\n" < file | sed 's/DESCR/\n&/g; $ s/$/\n/' |
   sed -rn '3,$ s/DESCR: "([^"]+).*SN: ([^[:space:]]+).*/\1,\2/p'