Linux 如何使用grep和sed打印多个字符串?

Linux 如何使用grep和sed打印多个字符串?,linux,sed,grep,command,Linux,Sed,Grep,Command,假设我有一个日志文件或文本文件,如下所示 16 Dec 2014 11:20:00 [INFO] com.example.Test.java PlaneName: JetAirways360 This flight just cleaned up 16 Dec 2014 11:22:01 [INFO] com.example.Test.java PlaneName: JetAirways360 This flight is in queue 16 Dec 2014 11:23:02 [INFO]

假设我有一个日志文件或文本文件,如下所示

16 Dec 2014 11:20:00 [INFO] com.example.Test.java PlaneName: JetAirways360 This flight just cleaned up
16 Dec 2014 11:22:01 [INFO] com.example.Test.java PlaneName: JetAirways360 This flight is in queue
16 Dec 2014 11:23:02 [INFO] com.example.Test.java PlaneName: JetAirways360 This flight passengers loaded
16 Dec 2014 11:24:03 [INFO] com.example.Test.State.java PlaneName: JetAirways360 This flight ready to take off
16 Dec 2014 11:25:00 [INFO] com.example.Test.State.java PlaneName: JetAirways360 This flight took off
17 Dec 2014 11:25:00 [INFO] com.example.Test.java PlaneName: JetAirways360 This flight returned back
现在想象一下,我这个日志文件已经完全填满了很多航班信息。可以听到查找特定航班信息的声音。现在我想grep看看下面的细节

16 Dec 2014 11:20:00 This flight just cleaned up
16 Dec 2014 11:22:01 This flight is in queue
16 Dec 2014 11:23:02 This flight passengers loaded
16 Dec 2014 11:24:03 This flight ready to take off
16 Dec 2014 11:25:00 This flight took off
17 Dec 2014 11:25:00 This flight returned back
如何使用grep和sed命令执行此操作

grep 'JetAirways360' lofFile | sed -e 's/\(.*\) \[INFO.*JetAirways360\(.*\)/\1 \2/g'
来解释这一点

  • 首先,我将对所有包含JetAirways360的日志条目进行灰显
  • 我正在使用sed。每个括号(.)都是我试图从日志中得到的\1代表第一个(.)和\2代表第二个(.*)。它就像我从原始行剪切的字符串值的打印语句
  • 详情:

  • sed正则表达式应包含此s//g
  • \1和\2是(.*)的打印语句
  • (.)表示为(.)。逃逸序列
  • s/(.*)[INFO这解释了如何将所有字符放在括号中,直到您看到[INFO(我已将转义字符\for[和[INFO])。这就是我如何使用\1选择和打印日期的原因
  • [INFO.JetAirways360(.)这解释了,在看到[INFO]后开始忽略,直到看到JetAirways360。之后,将所有剩余字符放在括号中。这就是我如何使用\2选择并打印日志消息的原因
  • 来解释这一点

  • 首先,我将对所有包含JetAirways360的日志条目进行灰显
  • 我正在使用sed。每个括号(.)都是我试图从日志中获取的内容。\1代表第一行(.),而\2代表第二行(.*)。这与我从原始行剪切的字符串值的打印语句类似
  • 详情:

  • sed正则表达式应包含此s//g
  • \1和\2是(.*)的打印语句
  • (.)表示为(.)转义序列
  • s/(.*)[INFO这解释了如何将所有字符放在括号中,直到您看到[INFO(我已将转义字符\for[和[INFO])。这就是我如何使用\1选择和打印日期的原因
  • [INFO.JetAirways360(.)这解释了,在看到[INFO]后开始忽略,直到看到JetAirways360。之后,将所有剩余字符放在括号中。这就是我如何使用\2选择并打印日志消息的原因
  • 这可能适用于您(GNU-sed):

    这会将文件的第一部分保存在反向引用中,并用它替换剩余文件的一部分。

    这可能适用于您(GNU-sed):


    这会将文件的第一部分保存在反向引用中,并用它替换剩余文件的一部分。

    这对于
    awk
    文件很简单

    awk -F" [[]|JetAirways360 " '{print $1,$3}' file
    16 Dec 2014 11:20:00 This flight just cleaned up
    16 Dec 2014 11:22:01 This flight is in queue
    16 Dec 2014 11:23:02 This flight passengers loaded
    16 Dec 2014 11:24:03 This flight ready to take off
    16 Dec 2014 11:25:00 This flight took off
    17 Dec 2014 11:25:00 This flight returned back
    

    这对于
    awk
    文件很简单

    awk -F" [[]|JetAirways360 " '{print $1,$3}' file
    16 Dec 2014 11:20:00 This flight just cleaned up
    16 Dec 2014 11:22:01 This flight is in queue
    16 Dec 2014 11:23:02 This flight passengers loaded
    16 Dec 2014 11:24:03 This flight ready to take off
    16 Dec 2014 11:25:00 This flight took off
    17 Dec 2014 11:25:00 This flight returned back
    

    使用sed有很多方法,下面的命令也可以使用

       sed 's#\([[:digit:]]\{2,2\}.*[[:digit:]]\{2,2\}:[[:digit:]]\{2,2\}:[[:digit:]]\{2,2\}\).*PlaneName.*JetAirways360 \(.*\)#\1 \2#g' 'my_log_file'
    
    它标记该行的前两位数字,直到飞行时间,并记住它。然后sed搜索该行以查找JetAirways360,在该名称后标记该行的其余部分。然后将这两种模式合并

    使用grep和cut

    另一个不使用grep或sed的简单技巧是使用“cut”(尽管这可能与回答您的问题无关)

    从字段(本例中为列)1到4打印,然后从字段9开始打印

    使用“切割”的结果

    注意:这只是剪切您需要的列,并且输出不涉及grepping或“sedding”

    您还可以使用grep作为平面名称,该名称将打印具有该平面名称的所有线,然后使用“剪切”

    示例

    grep "JetAirways36" 'my_log.txt'|cut -d ' ' -f1-4,9-
    

    使用sed有很多方法,下面的命令也可以使用

       sed 's#\([[:digit:]]\{2,2\}.*[[:digit:]]\{2,2\}:[[:digit:]]\{2,2\}:[[:digit:]]\{2,2\}\).*PlaneName.*JetAirways360 \(.*\)#\1 \2#g' 'my_log_file'
    
    它标记该行的前两位数字,直到飞行时间,并记住它。然后sed搜索该行以查找JetAirways360,在该名称后标记该行的其余部分。然后将这两种模式合并

    使用grep和cut

    另一个不使用grep或sed的简单技巧是使用“cut”(尽管这可能与回答您的问题无关)

    从字段(本例中为列)1到4打印,然后从字段9开始打印

    使用“切割”的结果

    注意:这只是剪切您需要的列,并且输出不涉及grepping或“sedding”

    您还可以使用grep作为平面名称,该名称将打印具有该平面名称的所有线,然后使用“剪切”

    示例

    grep "JetAirways36" 'my_log.txt'|cut -d ' ' -f1-4,9-
    
    如果您喜欢使用新命令
    flygrep

    #!/usr/bin/perl -n 
    BEGIN{ $fl = shift;}   
    print if s!.INFO.*Name: $fl !! 
    
    用法:
    flygrep JetAirways360文件

    sed -n '/\[.*JetAirways360/ s///p' YourFile
    
    如果您喜欢使用新命令
    flygrep

    #!/usr/bin/perl -n 
    BEGIN{ $fl = shift;}   
    print if s!.INFO.*Name: $fl !! 
    
    用法:
    flygrep JetAirways360文件

    sed -n '/\[.*JetAirways360/ s///p' YourFile
    
    你应该根据你的样品做你的工作


    应该根据您的示例执行您的工作

    它稍微依赖于flyid,但这是一个非常好的解决方案!在这里解释什么是{21}和{54}会很好。如果我能理解命令,我可以针对不同的情况进行修改。Thanks@RaviKrishnaP
    {21}
    表示21个字符占用的空间,在您提供的示例中,第一行为
    2014年12月16日11:20:00
    。好的。感谢您的解释。此字符位置是一个假设,可能不会一直保持不变。21个字符是,它保持正确,但不是54个字符。检查第5行和第6行。(我只是更新了它以避免假设。抱歉,我应该先这样做)。它稍微依赖于flyid,但这是一个非常好的解决方案!在这里解释什么是{21}和{54}会很好。如果我能理解命令,我可以针对不同的情况进行修改。Thanks@RaviKrishnaP
    {21}
    表示21个字符占用的空间,在您提供的示例中,第一行为
    2014年12月16日11:20:00
    。好的。感谢您的解释。此字符位置是一个假设,可能不会一直保持不变。21个字符是,它保持正确,但不是54个字符。检查第5行和第6行。(我只是更新了它以避免假设。对不起,我应该先这么做)。我永远不会想到把搜索模式放在FS中!很好!你能给我解释一下co吗