sed – 传递匹配到外部命令

我写了一个使用sed的脚本来改变这个:

kaefert@Ultrablech ~ $ cat /sys/class/power_supply/BAT0/uevent POWER_SUPPLY_NAME=BAT0 POWER_SUPPLY_STATUS=Full POWER_SUPPLY_PRESENT=1 POWER_SUPPLY_TECHNOLOGY=Li-ion POWER_SUPPLY_CYCLE_COUNT=0 POWER_SUPPLY_VOLTAGE_MIN_DESIGN=7400000 POWER_SUPPLY_VOLTAGE_NOW=8370000 POWER_SUPPLY_POWER_NOW=0 POWER_SUPPLY_ENERGY_FULL_DESIGN=45640000 POWER_SUPPLY_ENERGY_FULL=44541000 POWER_SUPPLY_ENERGY_NOW=44541000 POWER_SUPPLY_MODEL_NAME=UX32-65 POWER_SUPPLY_MANUFACTURER=ASUSTeK POWER_SUPPLY_SERIAL_NUMBER= 

转换为像这样的csv文件格式:

 kaefert@Ultrablech ~ $ Documents/Asus\ Zenbook\ UX32VD/power_to_csv.sh "date";"status";"voltage µV";"power µW";"energy full µWh";"energy now µWh" 2012-07-30 11:29:01;"Full";8369000;0;44541000;44541000 2012-07-30 11:29:02;"Full";8369000;0;44541000;44541000 2012-07-30 11:29:04;"Full";8369000;0;44541000;44541000 ... (in a loop) 

我现在想要的是将这些数字除以1.000.000,以使它们不代表μV,而代替μW代替V和W,以便快速浏览它们。 当然,我可以手动完成后,一旦我打开这个csv内libre办公室calc,但我想自动化它。

所以我发现,我可以在sed之间调用外部程序,如下所示:

 ... s/\nPOWER_SUPPLY_PRESENT=1\nPOWER_SUPPLY_TECHNOLOGY=Li-ion\nPOWER_SUPPLY_CYCLE_COUNT=0\nPOWER_SUPPLY_VOLTAGE_MIN_DESIGN=7400000\nPOWER_SUPPLY_VOLTAGE_NOW=\([0-9]\{1,\}\)/";'`echo 0`'\1/ 

而且我可以通过像这样的东西来获得我想要的值:

 echo "scale=6;3094030/1000000" | bc | sed 's/0\{1,\}$//' 

但现在的问题是,如何将我的匹配“\ 1”传递给外部命令?

如果你有兴趣查看完整的脚本,你可以在这里find它: http : //koega.no-ip.org/mediawiki/index.php/Battery_info_to_csv

Solutions Collecting From Web of "sed – 传递匹配到外部命令"

如果你的sed是GNU sed。 您可以使用'e'在sed命令中将匹配的组传递给外部命令/工具。

一个例子可能有助于说清楚:

说,你有一个问题:
你有一个字符串"120+20foobar"现在你想得到120 + 20部分的计算结果,并将“oo”替换为“foobar”部分的“xx”。

请注意,这个例子不是为了解决上面的问题,只是为了显示sed'e'的用法

所以你可以在第一轮比赛中打120+20 ,然后在第二组中休息,然后把两组分到不同的命令/工具中,然后得到结果。 喜欢:

  kent$ echo "100+20foobar"|sed -r 's#([0-9+]*)(.*)#echo \1 \|bc\;echo \2 \| sed "s/oo/xx/g"#ge' 120 fxxbar 

这样,你就可以把许多se nest放入另一个,直到你迷路。 :d

由于sed本身并不算算术,所以我会推荐使用awk来实现这样的功能,例如,将第三,第五和第六个域划分为一百万像这样的东西:

  awk -F';' -v OFS=';' ' NR == 1 NR != 1 { $3 /= 1e6 $5 /= 1e6 $6 /= 1e6 print }' 

说明

  • -F';'-v OFS=';' 指定输入和输出字段分隔符。
  • NR == 1通过第一行而不改变。
  • NR != 1如果不是第一行,则划分并打印。

直接除以100万,你这样做:

 Q='3094030/1000000' sed ':r /^[[:digit:]]\{7\}/{s$\([[:digit:]]*\)\([[:digit:]]\{6\}\)/1000000$\1.\2$;p;d};s:^:0:;br;d'