组合多个 sed 命令 [英] Combine multiple sed commands

查看:72
本文介绍了组合多个 sed 命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具有以下文件:

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

到目前为止我的代码:

# 获取带有  的行标签猫 tmp.txt |grep '<td>[0-9]*.[0-9]' >tmp2.txt# 删除空格sed -i 's/[\t ]//g' tmp2.txt# 删除 <td>标签猫 tmp2.txt |sed "s/<td>//g" >tmp3.txt# 删除 "kB/s (0.0%)"猫 tmp3.txt |sed "s/kB\/s\((.*)\)//g" >tmp4.txt# 删除 </td>标记并保存到 traffic.txt猫 tmp4.txt |sed "s/<\/td>//g" >流量.txt#rm -R -f tmp*

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

提前致谢,马利

解决方案

使用 -e 选项.在man sed

中查找

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

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

你也可以用另一种方式写成:

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

\+ 匹配一个或多个实例,但它不适用于非 GNU 版本的 sed.(例如,Mac 有 BSD)

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

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

顺便提一下,您也可以简单地通过每个 sed 将输出通过管道传输,而不是保存每个输出,我看到人们通常会这样做:

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

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

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

解决方案

Use the -e option. Look it up in man sed

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.

这篇关于组合多个 sed 命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆