组合多个 sed 命令 [英] Combine multiple sed commands
问题描述
具有以下文件:
<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天全站免登陆