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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11719011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:54:16  来源:igfitidea点击:

sed - pass match to external command

linuxbashsedcss

提问by kaefert

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. 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.

我现在想要的是将这些数字中的每一个除以 1.000.000,以便它们不代表 μV,而是代表 V 和 W 而不是 μW,以便快速浏览时可以轻松解释它们。当然,一旦我在 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`'/

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

回答by Kent

if your sed is GNU sed. you can use 'e' to pass matched group to external command/tools within sed command.

如果您的 sed 是 GNU sed。您可以使用“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+20in the first match group, and rest in 2nd group, then pass two groups to different command/tools and then get the result. like:

所以你可以120+20在第一个比赛组中进行,然后在第二组中休息,然后将两组传递给不同的命令/工具,然后得到结果。喜欢:

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

in this way, you could nest many seds one in another one, till you get lost. :D

通过这种方式,您可以将许多 sed 嵌套在另一个 sed 中,直到您迷路。:D

回答by Thor

As seddoesn't do arithmetic on its own I would recommend using awkfor something like this, e.g. to divide 3rd, 5th and 6th field by a million do something like this:

由于sed本身不进行算术运算,我建议将其awk用于类似的操作,例如将第 3、5 和 6 字段除以一百万,请执行以下操作:

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

Explanation

解释

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

回答by alinsoar

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$.$;p;d};s:^:0:;br;d'