因此,仅当我使用要处理的特定日志集时,才使用cat拉开文件,然后使用grep获取匹配行只能使我走得很远。它需要一种将线与模式匹配的方法,但只需要在匹配后返回该线的一部分。比赛前后的部分会不断变化。我曾经使用sedawk玩过游戏,但无法弄清楚如何过滤该行以删除比赛之前的部分,或者仅在比赛之后返回该部分,无论哪种都可以。
这是我需要过滤的一行示例:

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系统,但是我无法安装任何额外的辅助工具。

评论

@Gilles,奇怪,当我搜索时,它没有弹出,尽管我没有使用最终使用的标题...但是它没有显示在标题下方的屏幕中。无论如何,尽管我需要比赛后的整行内容,而不是第一个单词,但这可能会让我得到想要的结果,但可能并不需要太多改变。

它的头衔糟透了。我偷了你的,很好。采取sed解决方案,不要特别对待空格。

@Gilles,我不太确定该怎么做。我仍在学习sed。

也类似于unix.stackexchange.com/questions/24089/…。

@ shaa0601我不明白您的问题,要在没有格式的情况下添加注释特别困难。提出一个新的,独立的问题。

#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