组合多个sed命令

Mar*_*ley 5 regex shell sed

拥有以下文件:

<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>
Run Code Online (Sandbox Code Playgroud)

我想获取每秒之间的值<td></td>(并将其保存到文件),如下所示:

8.3
4.2
Run Code Online (Sandbox Code Playgroud)

我的代码到目前为止:

# 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*
Run Code Online (Sandbox Code Playgroud)

我怎么能这样做呢?这段代码真的很无聊..

谢谢你,马利

Har*_*non 11

使用该-e选项.仔细查看man sed

所以在你的情况下你可以这样做:

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
Run Code Online (Sandbox Code Playgroud)

您也可以用另一种方式编写它:

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

\+场比赛的一个或多个实例,但它不能在非GNU版本的sed的工作.(例如,Mac有BSD)

在下面的@ tripleee评论的帮助下,这是我能得到的最精致的版本,它也适用于非GNU版本sed:

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

作为旁注,你也可以简单地通过每个sed管道输出,而不是保存每个输出,这是我看到人们通常为临时任务做的事情:

  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
Run Code Online (Sandbox Code Playgroud)

-e选项是更有效的,但管道的选择是更方便,我猜.

  • 你可以取消`cat`,例如`grep'...'tmp.txt | ...` (2认同)