gpt4 book ai didi

linux - 抓取屏幕输出并解析为 csv 的 bash 脚本

转载 作者:太空狗 更新时间:2023-10-29 11:17:52 24 4
gpt4 key购买 nike

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

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

它的工作或多或少,但有两件事我遇到了困难。

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

  2. 如何使用命令 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 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 文件(它只是用来模拟运行 chk 两次的输出,以演示 awk 脚本的工作)替换为当前注释的out 脚本开头的行,并将末尾的 }' 替换为当前注释掉的 }' >> "$outfile" 并更改顺序split() 命令中您认为合适的字段。

请注意,上述内容与您今天所见的显着差异是:

  1. 您不再有显式的 shell 循环,而是使用 xargs 遍历输入文件内容(请参阅 why-is-using-a-shell-loop-to-process-text-considered-bad-practice 了解其重要性),并且
  2. 您现在对 chk 的所有调用的输出运行一次 awk,而不是对 chk 的每个单独调用运行一次 awk。

关于linux - 抓取屏幕输出并解析为 csv 的 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37317835/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com