将程序输出的逐行块转换为 CSV,同时删除行标题

将程序输出的逐行块转换为 CSV,同时删除行标题

需要你的帮助,我的命令输出是:

Server1:  
CPU(S):  8  
RAM: 24  
Socket: 2  

Server2:  
CPU(S):  16   
RAM: 32   
Socket: 5 

期望的输出:

Server1:,8,24,2  
Server2:,16,32,5    

答案1

awk '
  NF==1 { printf "%s%s", NR==1 ? "" : ORS, $1 }
  NF==2 { printf ",%s", $2 }
  END   { printf "%s", ORS }
' file
  • 如果该行包含一个字段:
    • 如果这不是第一行,则打印换行符
    • 打印字段1
  • 如果该行包含两个字段,则打印逗号和 field2
  • 最后,打印换行符

答案2

$ awk -v RS= -v OFS=',' '{print $1, $3, $5, $7}' file
Server1:,8,24,2
Server2:,16,32,5

答案3

# will be used to remember the previous line
b=;
while read -r a; do 
 # if the previous line was empty, then this line is a title line
 if [ "$b" == "" ]; 
  then echo;
  echo -n $a; 
 # else only output everything after ": "
 else IFS=": " read -r _ digs <<< "$a"; 
 # don't want to output a comma for a blank line
  if [ "$a" != "" ]; 
   then echo -n ,$digs;
  fi;
 fi;
 b=$a; 
done < 2

输出:

 
Server1:,8,24,2  
Server2:,16,32,5 

如果您想去掉开头的空格或在末尾添加一个空行,有几种方法可以做到这一点,这会使这个脚本变得更加复杂。如果您不知道该怎么做,请告诉我。

答案4

具有足够新的1版本磨坊主

mlr --idkvp --irs '\n\n' --ifs '\n' --ips ':' --ocsvlite --headerless-csv-output \
  clean-whitespace then put 'x=$[[1]]; $[[1]]="1"; $1=x' then remove-empty-columns \
  inputfile

解释:

  • --idkvp --irs '\n\n' --ifs '\n' --ips ':' --ocsvlite --headerless-csv-output将输入格式设置为段落模式,键值对以冒号分隔,每行一个字段;将输出格式设置为csvlite并禁止打印字段名称标题

  • clean-whitespace去除字段值中的前导和尾随空格

  • put 'x=$[[1]]; $[[1]]="1"; $1=x'将第一个字段的值设置为其名称2并将其名称设置为 "1" 。后者很重要,因为它使记录同质化 - 否则,即使--headerless-csv-output有效,米勒也会将每条记录打印为单独的 CSV 块。

  • remove-empty-columns因为--irs '\n\n' --ifs '\n', 一个单身的最终记录后的换行符被视为尾随空字段 - 这个组合将其删除

如果您希望:将 保留为第一个字段值的一部分,请在子句中更改$1=x为。$1=x.":"put

测试:

$ ~/src/miller/c/mlr --idkvp --irs '\n\n' --ifs '\n' --ips ':' --ocsvlite --headerless-csv-output \
>   clean-whitespace then put 'x=$[[1]]; $[[1]]="1"; $1=x' then remove-empty-columns \
>   inputfile
Server1,8,24,2
Server2,16,32,5

或保留:服务器名称中的:

$ ~/src/miller/c/mlr --idkvp --irs '\n\n' --ifs '\n' --ips ':' --ocsvlite --headerless-csv-output \
>   clean-whitespace then put 'x=$[[1]]; $[[1]]="1"; $1=x.":"' then remove-empty-columns \
>   inputfile
Server1:,8,24,2
Server2:,16,32,5

1在 Miller 5.6.2-dev 中有效,但在 Miller 5.3.0 中无效

2请注意,虽然看起来应该可以进行名称-值交换没有临时变量为

 put '$[ $[[1]] ]=$[[1]]; $[[1]]="1"'

这似乎具有创建具有不可打印名称的附加空值流内变量的副作用。

相关内容