源文件:
Linux 2.6.32-754.18.2.el6.x86_64 (myhostname) 03/24/2020 _x86_64_ (64 CPU)
07:32:01 PM 57 25.79 0.00 4.99 0.00 0.00 0.00 0.02 0.00 69.20
07:32:01 PM 58 26.38 0.00 3.43 0.00 0.00 0.00 0.02 0.00 70.17
07:32:01 PM 59 24.49 0.00 8.73 0.00 0.00 0.00 0.03 0.00 66.75
07:32:01 PM 60 20.31 0.00 5.60 0.00 0.00 0.00 0.02 0.00 74.08
07:32:01 PM 61 20.08 0.00 4.09 0.00 0.00 0.00 0.02 0.00 75.81
07:32:01 PM 62 21.33 0.00 5.23 0.00 0.00 0.00 0.02 0.00 73.42
07:32:01 PM 63 18.49 0.00 4.04 0.00 0.00 0.00 0.02 0.00 77.45
Average: CPU %usr %nice %sys %iowait %steal %irq %soft %guest %idle
Average: all 24.02 0.00 5.23 0.07 0.00 0.00 0.23 0.00 70.45
期望的输出:
myhostname 64 CPU 24.02 0.00 5.23 0.07 0.00 0.00 0.23 0.00 70.45
我能够从第一个字符串中提取所需的值:
sed -n '1{s|^[^(]*(\([^)]*\))[^(]*(\([^)]*\)).*|\1 \2|p}' test.txt
myhostname 64 CPU
但我不知道如何用它来替换。
我知道有其他(perl/awk)
方法可以满足需要,但我正在寻找sed
解决方案
更新: 唉,评论中的两条建议都没有给我想要的输出
[14]labuser@labhost:~> sed -n '1{s|^[^(]*(\([^)]*\))[^(]*(\([^)]*\)).*|\1 \2|;h;};${H;x;s/\n.*all//;p;}' test.txt
isgmwapp6n1 64 CPU
[14]user@labhost:~> sed -n '1h;${H;x;s/.*(\([^)]*\)).*(\([^)]*\))\n.*all/\1 \2/p;}' test.txt
[14]user@labhost:~/>
[14]user@labhost:~> sed --version |head -1
GNU sed version 4.2.1
[14]user@labhost:~> cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.10 (Santiago)
更新3我发现第一个建议的解决方案不起作用只是因为文件的最后一行是换行符。因此,我能够通过以下方式满足需要:
sed -n '1{s|^[^(]*(\([^)]*\))[^(]*(\([^)]*\)).*|\1 \2|;h;};/Average.*all/{H;x;s/\n.*all//;p;}' test.txt
@mosvy,非常感谢您的帮助。如果您将上述内容发布为答案,我会接受它。
答案1
sed -n '1h;/Average.*all/{H;x;s/.*(\([^)]*\)).*(\([^)]*\))\n.*all/\1 \2/p;}' /tmp/jeg
应该适用于任何版本的 sed。
第一行的命令h
将其内容复制到“保留空间”。
然后在最后一行(匹配的那个/Average.*all/
,不是$
因为文件末尾可能包含额外的空行),H;x;
(附加到保留空间+交换保留和模式空间)将在其前面添加第一行,然后将s/../../p
修剪删除不需要的东西并打印出来。