您好我有一个大文件,可以快速更新。它存储了很多FIX-ORDER消息。每个订单都包含在以“FIXES”开头的部分中,并以“Committed”结尾。在每个订单部分中,修复消息位于第一部分,后面是第二部分中的其他消息。 请参阅下面的输入样本和输出样本。
简而言之,我喜欢grep文件并逐行打印最后一个订单部分 并确保修复消息也打印在各行上。见下面的第二部分,这是我需要的最终出版物。
如果您能提供帮助,请告诉我
在订单部分中启动文本(让我们称之为订单A)
FIXES LIMIT CHECK ON:
FIX MESSAGE SECTION
FIXES LIMIT CHECK ON: 8=FIX.4.2;9=0;35=D;10=100; (Client.123.600)
修复消息部分+其他日志消息,直到我们到达单词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
如果可能,我只想使用一个命令行;输出有两部分。请在回答之前阅读这两个部分:
第一部分)我喜欢使用一个命令从“FIXES LIMIT CHECK ON:”开始的行中将每个订单部分gred到单词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
第二部分)
I like to print each Fix message that is divided by ";" in a new line
please note that the last entry of the fix message is (Client.123.600)
so my final out put should look like this
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
答案 0 :(得分:1)
修改如下:
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 }'
答案 1 :(得分:0)
grep -n '^FIXES '
为了让批评者高兴,我会解释。
在第一个命令中,tail -1
查找以&#39; FIXES&#39;开头的所有行。并给出了行号,cut -d: -f1
部分只给出了最后一行,sed -n
解析了行号。
在第二个命令中,sed
除非我们发送&#34; print&#34;否则不会打印任何内容。命令。我们的&#34; print&#34;命令告诉sed
从我们找到的行号打印到#34; Committed&#34;的下一个实例。我们将这些行发送到另一个<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.jboss.com/xml/ns/javaee
http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
<context-root>/</context-root>
</jboss-web>
,用冒号或分号(我们找到的任何一个)替换冒号和分号(后跟任意数量的空格)和换行符。
答案 2 :(得分:0)
使用GNU awk for gensub():
$ 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)
在上述情况下,预期输出将是中间块(具有从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