Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed - pass match to external command

Tags:

linux

css

bash

sed

I have written a little script using sed to transform this:

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:

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.

So what I found is, that I can call external programs in between sed, like this:

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

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

like image 927
kaefert Avatar asked Jul 30 '12 09:07

kaefert


People also ask

Can you pipe to sed?

sed can be used with other CLI tools through pipelines. Since sed can read an input stream, CLI tools can pipe data to it. Similarly, since sed writes to stdout, it can pipe its output to other commands. The sed and awk examples illustrate this.

What is P option in sed?

In sed, p prints the addressed line(s), while P prints only the first part (up to a newline character \n ) of the addressed line. If you have only one line in the buffer, p and P are the same thing, but logically p should be used.

What does D mean in sed?

The d command is used to delete lines. After sed copies a line from a file and puts it into a pattern buffer, it processes commands on that line, and, finally, displays the contents of the pattern buffer on screen.

How does sed command work?

The sed program is a stream editor that receives its input from standard input, changes that input as directed by commands in a command file, and writes the resulting stream to standard output. A stream of ASCII characters either from one or more files or entered directly from the keyboard.


1 Answers

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

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.

Note that this example is not for solving the problem above, just for showing the sed 'e' usage

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

like image 121
Kent Avatar answered Oct 01 '22 05:10

Kent