Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine multiple sed commands [duplicate]

Tags:

regex

shell

sed

having the following file:

<tr class="in">
  <th scope="row">In</th>
  <td>1.2 kB/s (0.0%)</td>
  <td>8.3 kB/s (0.0%) </td>
  <td>3.2 kB/s (0.0%) </td>
</tr>
<tr class="out">
  <th scope="row">Out</th>
  <td>6.7 kB/s (0.6%) </td>
  <td>4.2 kB/s (0.1%) </td>
  <td>1.5 kB/s (0.6%) </td>
</tr>

I want to get the values between each second <td></td> (and save it to a file) like this:

8.3
4.2

My code so far:

# get the lines with <td> tags
cat tmp.txt | grep '<td>[0-9]*.[0-9]' > tmp2.txt

# delete whitespaces
sed -i 's/[\t ]//g' tmp2.txt

# remove <td> tag
cat tmp2.txt | sed "s/<td>//g" > tmp3.txt

# remove "kB/s (0.0%)"
cat tmp3.txt | sed "s/kB\/s\((.*)\)//g" > tmp4.txt

# remove </td> tag and save to traffic.txt
cat tmp4.txt | sed "s/<\/td>//g" > traffic.txt

#rm -R -f tmp*

How can I do this the common way? This code is really noobish..

Thanks in Advance, Marley

like image 772
Marley Avatar asked May 31 '12 10:05

Marley


People also ask

Which option is used to combine multiple sed commands?

In this article let us review how to combine multiple sed commands using option -e as shown below. Note: -e option is optional for sed with single command. sed will execute the each set of command while processing input from the pattern buffer.

How do you use multiple sed commands in one line?

There are several methods to specify multiple commands in a sed program. Using newlines is most natural when running a sed script from a file (using the -f option). The { , } , b , t , T , : commands can be separated with a semicolon (this is a non-portable GNU sed extension).

How do you do multiple sed replacements?

You can tell sed to carry out multiple operations by just repeating -e (or -f if your script is in a file). sed -i -e 's/a/b/g' -e 's/b/d/g' file makes both changes in the single file named file , in-place.

How do you pipe a sed command?

Use the -e option (if using GNU sed). From the manual: e [command] This command allows one to pipe input from a shell command into pattern space. Without parameters, the e command executes the command that is found in pattern space and replaces the pattern space with the output; a trailing newline is suppressed.


1 Answers

Use the -e option (if using GNU sed). From the manual:

e [command] This command allows one to pipe input from a shell command into pattern space. Without parameters, the e command executes the command that is found in pattern space and replaces the pattern space with the output; a trailing newline is suppressed.

If a parameter is specified, instead, the e command interprets it as a command and sends its output to the output stream. The command can run across multiple lines, all but the last ending with a back-slash.

In both cases, the results are undefined if the command to be executed contains a NUL character.

Note that, unlike the r command, the output of the command will be printed immediately; the r command instead delays the output to the end of the current cycle.

So in your case you could do:

cat tmp.txt | grep '<td>[0-9]*.[0-9]' \
| sed -e 's/[\t ]//g' \
-e "s/<td>//g" \
-e "s/kB\/s\((.*)\)//g" \
-e "s/<\/td>//g" > traffic.txt

You can also write it in another way as:

grep "<td>.*</td>" tmp.txt | sed 's/<td>\([0-9.]\+\).*/\1/g'

The \+ matches one or more instances, but it does not work on non-GNU versions of sed. (Mac has BSD, for example)

With help from @tripleee's comment below, this is the most refined version I could get which will work on non-GNU versions of sed as well:

sed -n 's/<td>\([0-9]*.[0-9]*\).*/\1/p' tmp.txt

As a side note, you could also simply pipe the outputs through each sed instead of saving each output, which is what I see people generally do for ad-hoc tasks:

  cat tmp.txt | grep '<td>[0-9]*.[0-9]' \
    | sed -e 's/[\t ]//g' \
    | sed "s/<td>//g" \
    | sed "s/kB\/s\((.*)\)//g" \
    | sed "s/<\/td>//g" > traffic.txt

The -e option is more efficient, but the piping option is more convenient I guess.

like image 132
Hari Menon Avatar answered Oct 02 '22 23:10

Hari Menon