Linux 获取屏幕输出并解析为csv的bash脚本

Linux 获取屏幕输出并解析为csv的bash脚本,linux,bash,shell,awk,Linux,Bash,Shell,Awk,当我运行一个名为chk的自定义脚本并将其输出到csv时,我正在编写一个bash脚本来获取屏幕输出 chk命令的屏幕输出示例 type: ISDSL ACCESS ADSL circt: 219317638 speed: 4096 rroutr: Billion 7404 (IS) intr: 196.214.12.124/30 vrf: PCTPT 我的命令$line可以是任何行标记 chk $line | egrep 'type|circt|speed|rroutr|in

当我运行一个名为chk的自定义脚本并将其输出到csv时,我正在编写一个bash脚本来获取屏幕输出

chk命令的屏幕输出示例

type:   ISDSL ACCESS ADSL
circt:  219317638
speed:  4096
rroutr: Billion 7404 (IS)
intr:   196.214.12.124/30
vrf:     PCTPT
我的命令$line可以是任何行标记

chk $line | egrep 'type|circt|speed|rroutr|intr|vrf' | awk'{if(NR==1){print "  Circuit,Speed,CE,,WAN IP,VRF";}
else{print $2 $3} ORS=","}'
此操作的输出为

Circuit,Speed,CE,,WAN IP,VRF
219317638,4096,Billion,196.214.12.124/30,PCTPT
接下来,我希望向脚本输入一个项目列表($line),我希望在其中运行自定义脚本,并将每个屏幕输出解析为csv文件

# This script takes in a file of many $line's and runs the chk command on each line usage  ./parsechk2csv <filename>
#!/bin/bash
cat $1|while read line; do
echo "$line\n";
chk $line | egrep 'type|circt|speed|rroutr|intr|vrf' | awk'{if(NR==1) {print "";}else{print $2 $3} ORS=","}' >> test.csv
done
#此脚本接收多个$line的文件,并在每一行上运行chk命令。/parsechk2cv
#!/bin/bash
cat$1 |读线时;做
回显“$line\n”;
chk$line | egrep’type | circt | speed | rroutr | intr | vrf | awk{if(NR==1){print”“;}else{print 2$3}ORS=“,”}>test csv
完成
它或多或少起作用,但有两件事我有困难

  • 如何在最终脚本中包含csv文件标题,而不在shell脚本中循环始终重写标题(您会注意到,我在当前脚本awk命令中遗漏了标题)。使用NR==1还会覆盖我需要的屏幕输出中的第一行

  • 如何使用命令args指定输出csv文件的名称。我试图重定向到>>$3.csv,但这不起作用


  • 不清楚输入文件的哪些行映射到输出中的哪些字段,因为您显示的值在标题行中的名称似乎没有意义,但这是您想要的方法:

    $ cat file
    first linetag
    type:   ISDSL ACCESS ADSL
    circt:  219317638
    speed:  4096
    routr:  ctn3-dsl/e0
    rroutr: Billion 7404 (IS)
    intr:   196.214.12.124/30
    vrf:    first idk
    
    second linetag
    type:   Next fake ACCESS
    circt:  123456
    speed:  2020
    routr:  foo-hspd/e1
    rroutr: dozens 6564 (IS)
    intr:   100.200.30.304/27
    vrf:    second idk
    

    只需将
    cat文件
    (为了演示awk脚本的工作,它只是用来模拟运行
    chk
    两次的输出)替换为脚本开头当前注释掉的行,并将结尾的
    }
    替换为当前注释掉的
    }>“$outfile”
    并根据需要更改
    split()
    命令中字段的顺序

    请注意,上述与您今天的显著差异在于:

  • 您不再有显式的shell循环,而是使用xargs迭代输入文件的内容(请参阅了解原因),然后
  • 现在对所有chk调用的输出运行一次awk,而不是对每个单独的chk调用运行一次awk

  • 数据行中的条目小于标题行。。。这似乎是错误的。即使缺少一列,也必须插入占位符列。类似于
    2193176384096,,pep-ctn3-dsl/e0,Billion,196.214.12.124/30,
    Notice 2
    4096
    之后的
    。感谢您的反馈。我忘了提到我想添加$line变量作为csv文件中第一个字段的数据,不管您怎么评论,您的标题行中仍然有7个字段
    LineTag、Circuit、Type、PE、Speed、WAN IP、VRF
    ,awk输出中只有5个字段:
    2193176384096,pep-ctn3-dsl/e0,Billion,196.214.12.124/30,
    。(当我们将最后一个逗号作为第六个(空)字段的字段分隔符时为6),并且输入中只有6行。这个问题前后矛盾。例如,
    speed
    位于页眉的第5列和数据行的第2列(4096)。因此,编辑问题,纠正它,并添加示例输出您真正想要什么。谢谢Ed。非常感谢。为这些令人困惑的标题道歉。如果我想添加$line作为csv中的第一项,然后添加屏幕输出中的其他字段。基本上,$line将是linetag的值,我将添加另一个标题字段,以匹配我从屏幕输出中获取的内容。我更新了我的答案,但如果您只需编辑您的问题以显示简洁,可测试的样本输入和你想要的输出。谢谢Ed。我肯定会继续改进我现在的输入。我尝试了新的脚本,但在输出csv文件中似乎只有一行。在上一个脚本中,它为输入文件中的所有行生成csv。我将进一步调查,看不出是什么导致了它awk脚本将起作用,所以您只需要调查
    xargs…chk
    。试试
    
    
    $ cat tst.sh
    #infile="$1"
    #outfile="${2:-test.csv}"
    #<"$infile" xargs -d'\n' -n1 -Iline sh -c 'echo "line"; chk "line"' |
    cat file |
    awk -v RS= -F'\n' -v OFS="," '
    BEGIN {
        split("LineTag,Router,Type,Circuit,Speed,PE,WANIP,VRF",names,/,/)
        split("linetag,routr,type,circt,speed,rroutr,intr,vrf",abbrs,/,/)
    }
    NR==1 {
        for (i=1; i in names; i++) {
            printf "%s%s", (i>1?OFS:""), names[i]
        }
        print ""
    }
    {
        delete abbr2value
        abbr2value[abbrs[1]] = $1
        for (i=2; i<=NF; i++) {
            abbr = value = $i
            sub(/:.*/,"",abbr)
            sub(/[^:]+:[[:space:]]*/,"",value)
            abbr2value[abbr] = value
        }
        for (i=1; i in abbrs; i++) {
            printf "%s%s", (i>1?OFS:""), abbr2value[abbrs[i]]
        }
        print ""
    }'
    #}' >> "$outfile"
    
    $ ./tst.sh
    LineTag,Router,Type,Circuit,Speed,PE,WANIP,VRF
    first linetag,ctn3-dsl/e0,ISDSL ACCESS ADSL,219317638,4096,Billion 7404 (IS),196.214.12.124/30,first idk
    second linetag,foo-hspd/e1,Next fake ACCESS,123456,2020,dozens 6564 (IS),100.200.30.304/27,second idk