IT干货网

regex之组合多个 sed 命令

del 2025年12月25日 编程设计 225 0

这个问题在这里已经有了答案:





Combining two sed commands

(2 个回答)


5年前关闭。




有以下文件:

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

我想获得每秒之间的值 <td></td> (并将其保存到文件中)像这样:
8.3 
4.2 

到目前为止我的代码:
# 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* 

我怎样才能以常见的方式做到这一点?这段代码真的很菜。。

提前致谢,
马利

请您参考如下方法:

使用 -e选项(如果使用 GNU sed)。来自 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.


所以在你的情况下,你可以这样做:
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 
你也可以用另一种方式写成:
grep "<td>.*</td>" tmp.txt | sed 's/<td>\([0-9.]\+\).*/\1/g' 
\+匹配一个或多个实例,但它不适用于非 GNU 版本的 sed。 (例如,Mac 有 BSD)
在下面@tripleee 评论的帮助下,这是我能得到的最精致的版本,它适用于 sed 的非 GNU 版本还有: 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 
-e选项更有效,但我猜管道选项更方便。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!