cat
拉开文件,然后使用grep
获取匹配行只能使我走得很远。它需要一种将线与模式匹配的方法,但只需要在匹配后返回该线的一部分。比赛前后的部分会不断变化。我曾经使用sed
或awk
玩过游戏,但无法弄清楚如何过滤该行以删除比赛之前的部分,或者仅在比赛之后返回该部分,无论哪种都可以。这是我需要过滤的一行示例:
2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.amd64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }
我需要的部分是“停顿”之后的所有内容。
这是我可以找出停顿的频率:
cat messages | grep stalled | wc -l
我需要做的是找出某个节点停顿了多少次(由该部分表示)如果我只是grep表示(例如20 :),它可能会返回软失败但没有停顿的行,这对我没有帮助,我只需要过滤停顿的部分,这样我就可以
出于所有意图和目的,这是一个具有标准GNU核心utils的freebsd系统,但是我无法安装任何额外的辅助工具。
#1 楼
规范工具为sed
。sed -n -e 's/^.*stalled: //p'
详细说明:
-n
表示不打印-e
后跟一个sed命令。s
是模式替换命令。正则表达式
^.*stalled:
与您要查找的模式匹配例如,加上任何前面的文字(.*
表示任何文字,并以^
开头表示匹配从行的开头开始)。请注意,如果stalled:
在该行上出现多次,则将匹配最后一次出现。最后的stalled:
意味着打印转换后的行。如果要保留匹配的部分,请使用向后引用:替换部分中的
p
表示图案中的
组内部的内容。在这里,您可以在替换部分再次写\(…\)
;当您要查找的模式比简单字符串更笼统时,此功能很有用。sed -n -e 's/^.*\(stalled: \)//p'
有时您需要在删除行的一部分后比赛。您可以通过在模式末尾包含
stalled:
(任何文本.*$
后跟行.*
的末尾)来将其包括在匹配项中。除非将零件放在替换文本中引用的组中,否则行的结尾将不在输出中。作为组和反向引用的进一步说明,此命令将交换零件比赛之前和比赛之后的部分。
sed -n -e 's/^\(.*\)\(stalled: \)\(.*\)$//p'
评论
我已经尝试了前两个示例,但似乎挂起了。我没有收到错误消息,也没有收到新的提示,什么也没有。
– MaQleod
2011年11月8日下午1:00
@MaQleod哦,它正在等待标准输入,这是终端,因为您尚未重定向它。在这里,您要执行输入重定向sed…<消息,因为您要处理文件中的数据。要对另一个命令产生的数据进行处理,可以使用管道:somecommand | sed…。
–吉尔斯'所以-不再是邪恶的'
11年8月8日在1:02
对,当天停电了。命令完美运行,谢谢。
– MaQleod
2011年11月8日在16:37
到目前为止,我所见过的最好的sed解释-谢谢!
–琼·沃兹沃思(Jon Wadsworth)
16 Sep 16 '17:47
@ungalcrys的短版是什么?这不等于我的答案中的任何命令。我建议将其写为sed's /^.* stalled //',因为-r特定于Linux,并且无法在其他系统(例如macOS)上运行,因此您不会从中受益。
–吉尔斯'所以-不再是邪恶的'
17年8月9日在10:19
#2 楼
您已经使用的另一个规范工具:grep
:例如:
grep -o 'stalled.*'
与Gilles的第二个选项具有相同的结果:
sed -n -e 's/^.*\(stalled: \)//p'
-o
标志返回表达式的--only-matching
部分,所以不是整个行-当然,通常由grep完成。要从输出中删除“停滞的:”,我们可以使用第三个规范工具,将其剪切:
结束。当然,这是优先选择的问题,但是我发现
cut
语法非常容易记住。评论
感谢您提及-o选项!我想指出的是,grep无法将\ n识别为换行符,因此您的第一个示例仅与前n个字符匹配。例如,回显“ Hello Anne” | grep -o'A [^ \ n] *'返回字符串A。但是,回显“ Hello Anne” | grep -o'A. *'返回预期的Anne,因为。匹配除换行符以外的任何字符。
–adamlamar
15年3月16日在21:52
注意,剪切定界符-d':'周围的引号已被@poige删除。我发现用引号容易记住,例如与-d''或-d';'。
–Anne van Rossum
17年7月10日在20:44
根据您的发现,记住-f 2也应该更容易使用引号。说真的,为什么不呢?
– poige
17年8月26日在10:26
因为分隔符像分号;而不是冒号:如果不加引号,其解释会有所不同。当然这是合乎逻辑的行为,但我仍然喜欢依靠肌肉记忆。我不想一次引用分隔符,而另一次不引用。就像我之前所说的那样,只是个人喜好:更容易记住。
–Anne van Rossum
17-10-7在18:09
。*所需的时间段对我来说很好用:cat filename | grep'仅返回此行xyz文本'| grep -o'xyz。*'返回xyz文本
–ron
17-12-12在19:01
#3 楼
我用ifconfig | grep eth0 | cut -f3- -d:
取了这个 [root@MyPC ~]# ifconfig
eth0 Link encap:Ethernet HWaddr AC:B4:CA:DD:E6:F8
inet addr:192.168.0.2 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:78998810244 errors:1 dropped:0 overruns:0 frame:1
TX packets:20113430261 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:110947036025418 (100.9 TiB) TX bytes:15010653222322 (13.6 TiB)
看起来像这样
[root@MyPC ~]# ifconfig | grep eth0 | cut -f3- -d:
C4:7A:4D:F6:B8
评论
这会回答问题吗?
–斯蒂芬·劳赫(Stephen Rauch)
17年3月31日下午4:56
您可以使用cat / sys / class / net / * / address,无需解析。
–Anne van Rossum
17年12月13日在16:58
如果只有C4:7A:4D:F6:B8出现在您的初始代码块中
– Zodzie
20年9月2日在21:24
#4 楼
您认为awk
的另一种规范工具可以与以下行一起使用:awk -F"stalled" '/stalled/{print }' messages
详细说明:
-F
定义了行的分隔符,即“停滞”。
查找分隔符之前的所有内容,并使用
处理之后的所有内容。/reg-ex/
搜索匹配的正则表达式,在这种情况下为“ stalled”。{print $<n>}
-打印n列。由于分隔符被定义为停顿,因此停顿后的所有内容均视为第二列。#5 楼
似乎有一种更简单的方法。只需执行以下操作即可:sed "s/installed.*//g"
删除“已安装”之后的所有单词。
for i in *
do
se=$(echo $i|sed "s/---.*//g")
echo $se
mv "$i" $se
done
评论
@Gilles,奇怪,当我搜索时,它没有弹出,尽管我没有使用最终使用的标题...但是它没有显示在标题下方的屏幕中。无论如何,尽管我需要比赛后的整行内容,而不是第一个单词,但这可能会让我得到想要的结果,但可能并不需要太多改变。它的头衔糟透了。我偷了你的,很好。采取sed解决方案,不要特别对待空格。
@Gilles,我不太确定该怎么做。我仍在学习sed。
也类似于unix.stackexchange.com/questions/24089/…。
@ shaa0601我不明白您的问题,要在没有格式的情况下添加注释特别困难。提出一个新的,独立的问题。