Linux 找到最后出现的字符串并在BASH中打印sed awk grep下面的所有内容

Linux 找到最后出现的字符串并在BASH中打印sed awk grep下面的所有内容,linux,bash,awk,sed,grep,Linux,Bash,Awk,Sed,Grep,嗨,我有一个大文件,不断得到快速更新。它存储了大量的订单信息。每个订单都包含在一个部分中,以“FIXES”开头,以“Committed”结尾。在每个订单部分中,第一部分是修复消息,第二部分是其他消息。 请参见下面的输入样本和输出样本 简而言之,我喜欢将文件grep并逐行打印最后一个订单部分 并确保修复消息也打印在单独的行上。见下文第二部分,这是我需要的最终输出 如果你能帮忙,请告诉我 在order部分开始文本(我们称之为orderA) 修复消息部分 FIXES LIMIT CHECK ON: 8

嗨,我有一个大文件,不断得到快速更新。它存储了大量的订单信息。每个订单都包含在一个部分中,以“FIXES”开头,以“Committed”结尾。在每个订单部分中,第一部分是修复消息,第二部分是其他消息。 请参见下面的输入样本和输出样本

简而言之,我喜欢将文件grep并逐行打印最后一个订单部分 并确保修复消息也打印在单独的行上。见下文第二部分,这是我需要的最终输出

如果你能帮忙,请告诉我

在order部分开始文本(我们称之为orderA)

修复消息部分

FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
修复消息部分+日志消息的其余部分,直到到达word Commit 请注意,每一行以括号结尾

FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1235  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1236  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed 
我喜欢做什么,如果可能的话,只使用一个命令行;输出有两个部分。回答前请阅读两部分:

第I部分)我喜欢使用命令将每个订单部分从“fixeslimitcheck ON:”开始的一行grep到单词Committed,因此基本上

FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1235  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed 
第II部)


修改如下:

tac <data_file> | sed -n -e '/Committed/,/FIXES LIMIT CHECK ON/p ; /FIXES LIMIT CHECK ON/q' | tac | sed -e '/Client/ { s/:\s?/:\n/g ; s/;\s*/;\n/g }'
tac | sed-n-e'/Committed/,/FIXES LIMIT CHECK ON/p/修复了/q'| tac | sed-e'/Client/{s/:\s?/:\n/g;s/;\s*/;\n/g}'上的限制检查
为了让批评家们高兴,我会解释

在第一个命令中,
grep-n'^FIXES'
查找所有以“FIXES”开头的行并给出行号,
tail-1
部分只给出最后一行,而
cut-d:-f1
解析出行号

在第二个命令中,
sed-n
不打印任何内容,除非我们向它发送一个“print”命令。我们的“print”命令告诉
sed
从我们找到的行号打印到下一个“Committed”实例。我们将这些行发送到另一个
sed
,该sed将冒号和分号(后跟任意数量的空格)替换为冒号或分号(以我们找到的为准)和换行符。

使用GNU awk for gensub()

大多数复杂性是为了确保它只打印最后一条完整的记录(即以“提交”结尾的记录)

下面是一个更好的示例输入文件,用于演示为什么需要上述逻辑:

$ cat file
stuff
FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1231  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1232  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1233  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed
foo
FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1235  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1236  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed
bar
FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1237  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1238  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1239  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
在上述情况下,预期的输出将是中间块(消息行从1234、1235和1236开始的块),而不是最后一个块,因为最后一个块没有以
Committed
结束,因此仍在通过生成它的任何命令写入输入文件的过程中。因此,文件中最后一个完成的块是中间的块,因此预期输出由上述awk命令生成:

$ awk -f tst.awk file
FIXES LIMIT CHECK ON:
8=FIX.4.2;
9=0;
35=D;
10=100;
(Client.123.600)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1235  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1236  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed

问题中有大量的
订单
,但没有显示一个完整的输入示例,也没有显示任何您自己努力解决的问题。祝您度过愉快的一天!!解释总是有助于增加任何答案的长期价值。您好,谢谢您的回复。该命令不起作用。我甚至一部分一部分地试过,文件很大,包含很多条目。我需要获取文件中的最后一个条目,您的命令不考虑它?除非我错了,否则它会寻找第一次出现的修复?我错了吗?请告诉我?同样,不确定为什么命令的第一部分不起作用?我是说sed-n'/^FIXES/,/Committ/p'对不起,我错过了“最后一条”部分。谢谢杰克,你真好,期待着看到修改后的版本。杰克,我会试试看的。我正试图寻找做同样事情的tac命令,但目前为止它不起作用。我告诉你这个命令部分有效。它会打印两次输出吗?不知道为什么?我还需要查找最后一次出现的修复?不知道你的剧本是怎么做到的?好像是在找文件中的第一个?嗨Ed。。我试了又试,我还是一样。它将结果打印两次。。不知道为什么。。请告诉我您是否可以提供一些输入,如果您有时间详细解释该命令,我可以自己解决它?我能够获得最后一次输出,因此现在只需将修复消息分解为不同的行。我没有意识到您只需要最后一次输出。对不起,错过了那个。我修改了它;不过不太漂亮。试试看,让我知道。嗨,艾德。。我不打算这么做,Thx,但看起来很复杂,不明白它是如何工作的,正如我提到的,只需要打印最后一个完整块确实会带来一些复杂性,因为您需要确保找到以修复开始的最后一个文本块,但如果当前文本块以提交结束,则只覆盖上一个文本块,因为这将是文件中的最后一个完整块,即使后面有修复行。但是,每个代码段本身都很简单。我添加了更好的示例输入,显示了为什么需要我发布的代码,并在每个代码块中添加了注释。发布的sed+其他工具解决方案将因该输入而失败,并具有其他功能issues@theuniverseisflat这对你不管用吗?如果它真的这样做了,那么看看下一步该怎么做。
$ last_entry_line=$(grep -n '^FIXES ' test.txt | tail -1 | cut -d: -f1 )
$ cat test.txt | sed -n "${last_entry_line},/Committ/p" | sed '/^FIXES/s/\([:;]\)\s*/\1;\n/g'
$ cat tst.awk
inMsgs {
    # Previous line must have been a FIXES.. line and we are
    # now in the messages lines so just append each of them
    # to the msgs variable as they are read.
    msgs = msgs $0 ORS
}
/Committed/ {
    # Found a "Committed" line so this is the end of a complete
    # block of input so save the contents of the current "fix"
    # and "msgs" variables to the "last read block" equivalents
    # and clear the "in messages block" flag.
    lastFix  = fix
    lastMsgs = msgs
    inMsgs   = 0
}
/^FIXES LIMIT CHECK ON:/ {
    # Found a FIXES... line so save that "fix" line, empty
    # the buffer of "msgs" and set the "in messages block flag"
    # so it is set when the next line is read.
    fix      = $0
    msgs     = ""
    inMsgs   = 1
}
END {
    # We have reached the end of the input file so insert newlines
    # where appropriate in the "lastFix" line then print it and
    # then print the lines stored in the "lastMsgs" variable.
    print gensub(/([^:]+:) ([^;]+;)([^;]+;)([^;]+;)([^;]+;) (.*)/,"\\1\n\\2\n\\3\n\\4\n\\5\n\\6",1,lastFix)
    printf "%s", lastMsgs
}
$ awk -f tst.awk file
FIXES LIMIT CHECK ON:
8=FIX.4.2;
9=0;
35=D;
10=100;
(Client.123.600)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1235  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1236  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed
$ cat file
stuff
FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1231  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1232  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1233  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed
foo
FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1235  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1236  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed
bar
FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
1237  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1238  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1239  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
$ awk -f tst.awk file
FIXES LIMIT CHECK ON:
8=FIX.4.2;
9=0;
35=D;
10=100;
(Client.123.600)
1234  abcdefg EFG/HIT [12355] debug JUN 20 17:25:34 Matched  (Match.c.t)
1235  cdghhhh ggg/HIT [19889] INFO JUN 20 17:25:34 Matched  (Found.c.t)
1236  abwwwfg EFG/HIT [12885] debug JUN 20 17:25:34 Matched  (Match.c.t)
Committed