简体   繁体   English

sed - 将匹配传递给外部命令

[英]sed - pass match to external command

I have written a little script using sed to transform this: 我用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= 

into a csv file format like this: 成为这样的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)

What I would like now is to divide each of those numbers by 1.000.000 so that they don't represent µV but V and W instead of µW, so that they are easily interpretable on a quick glance. 我现在想要的是将这些数字中的每一个除以1.000.000,这样它们不代表μV而是V和W而不是μW,因此它们很容易在快速浏览时解释。 Of course I could do this manually afterwards once I've opened this csv inside libre office calc, but I would like to automatize it. 当然,一旦我在libre office calc中打开这个csv,我就可以手动完成这个,但是我想自动化它。

So what I found is, that I can call external programs in between sed, like this: 所以我发现,我可以在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/

and that I could get values like I want by something like this: 并且我可以通过以下方式获得我想要的值:

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

But the problem now is, how do I pass my match "\\1" into the external command? 但现在的问题是,如何将匹配“\\ 1”传递给外部命令?

If you are interested in looking at the full script, you'll find it there: http://koega.no-ip.org/mediawiki/index.php/Battery_info_to_csv 如果您有兴趣查看完整的脚本,您可以在那里找到它: http//koega.no-ip.org/mediawiki/index.php/Battery_info_to_csv

if your sed is GNU sed. 如果你的sed是GNU sed。 you can use 'e' to pass matched group to external command/tools within sed command. 您可以使用'e'将匹配的组传递给sed命令中的外部命令/工具。

an example might be helpful to make it clear: 一个例子可能有助于说清楚:

say, you have a problem: 说,你有一个问题:
you have a string "120+20foobar" now you want to get the calculation result of 120+20 part, and replace "oo" to "xx" in "foobar" part. 你有一个字符串"120+20foobar"现在你想获得120 + 20部分的计算结果,并在“foobar”部分中将“oo”替换为“xx”。

Note that this example is not for solving the problem above, just for showing the sed 'e' usage 请注意,此示例不是用于解决上述问题,仅用于显示sed'e'用法

so you could make 120+20 in the first match group, and rest in 2nd group, then pass two groups to different command/tools and then get the result. 所以你可以在第一个匹配组中生成120+20 ,然后在第二个组中生成,然后将两个组传递给不同的命令/工具,然后获得结果。 like: 喜欢:

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

in this way, you could nest many seds one in another one, till you get lost. 通过这种方式,你可以在另一个中嵌入许多seds,直到你迷路为止。 :D :d

As sed doesn't do arithmetic on its own I would recommend using awk for something like this, eg to divide 3rd, 5th and 6th field by a million do something like this: 由于sed没有自己做算术,我建议使用awk的东西,例如将第3,第5和第6个字段除以100万像这样:

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

Explanation 说明

  • -F';' and -v OFS=';' -v OFS=';' specify the input and output field separator. 指定输入和输出字段分隔符。
  • NR == 1 pass first line through without change. NR == 1通过第一行而不做任何更改。
  • NR != 1 if it is not the first line, divide and print. NR != 1如果不是第一行,则分割并打印。

To divide by 1,000,000 directly, you do so : 要直接除以1,000,000,您需要这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM