我正在编写一个bash脚本来抓取屏幕输出,当我运行一个名为chk的自定义脚本并将其输出到csv。
chk命令的屏幕输出示例
type: ISDSL ACCESS ADSL circt: 219317638 speed: 4096 rroutr: Billion 7404 (IS) intr: 196.214.12.124/30 vrf: PCTPT
我的命令$行可以是任何linetag
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
在这之后,我想input到脚本的项目列表($行)我想要运行自定义脚本并parsing每个屏幕输出到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
它的工作或多或less,但有两件事我有困难。
如何在我的最终脚本中包含csv文件标题,而shell脚本中的循环始终不变地重写标题(您将注意到我将标题从我当前的脚本awk命令中删除)。 使用NR == 1也会覆盖我需要的屏幕输出中的第一行
如何使用命令args指定输出csv文件的名称。 我试图redirect到>> $ 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 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
只要用脚本开头的当前注释掉的行代替cat file
(它只是用来模拟两次运行chk
的输出,以演示awk脚本的工作情况),并在末尾替换}'
与当前注释}' >> "$outfile"
并根据您的意思更改split()
命令中字段的顺序。
请注意,以上与你今天的重大差异是: