bash 如何使用 grep 或 awk 从文件中提取特定块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/11593569/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use grep or awk to extract specific block from a file
提问by Mohit Kumar
I have a sample data in a log file
我在日志文件中有一个示例数据
NODE-ID> command1
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
NODE-ID> command2
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
NODE-ID> command3
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
节点 ID> 命令 1
Lorem ipsum dolor sat amet,consectetuer adipiscing elit,sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat。Ut wisi enim ad minim veniam, quis nostrud exerciation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat。
节点 ID> 命令 2
Lorem ipsum dolor sat amet,consectetuer adipiscing elit,sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat。Ut wisi enim ad minim veniam, quis nostrud exerciation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat。
节点 ID> 命令 3
Lorem ipsum dolor sat amet,consectetuer adipiscing elit,sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat。Ut wisi enim ad minim veniam, quis nostrud exerciation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat。
I have a file which is generated by sequential commands. I am not sure how can i extract data from the log file
我有一个由顺序命令生成的文件。我不确定如何从日志文件中提取数据
suppose if I need to extract data from file
假设我是否需要从文件中提取数据
NODE-ID> command1
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
节点 ID> 命令 1
Lorem ipsum dolor sat amet,consectetuer adipiscing elit,sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat。Ut wisi enim ad minim veniam, quis nostrud exerciation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat。
what is the best way to do so ? I have most my script written in shell script, I can use awk or sed. Please suggest
这样做的最佳方法是什么?我的大部分脚本都是用 shell 脚本编写的,我可以使用 awk 或 sed。请建议
回答by Seth Robertson
perl -ne 'sub BEGIN { $/="NODE-ID> "; } { if (/^command1/) { s:$/$::; print "$/$_"; }}'
Not sed/awk, but...it works.
不是 sed/awk,但是......它有效。
This isawk:
这是awk:
awk 'BEGIN { RS="NODE-ID> "; } /^command1/ { print RS sed -n '/^NODE-ID> command1/,/^NODE-ID> / { /^NODE-ID> command1/ { p; d; }; /^NODE-ID> /q; p }'
; }'
And inspired by CodeGnome, I add a sed option:
受 CodeGnome 的启发,我添加了一个 sed 选项:
$ sed -n '/command1/,/command2/ { /command2/q; p }' /tmp/foo
回答by Todd A. Jacobs
A Sed Solution
Sed 解决方案
It is certainly possible to do this with sed. For example, this command returns the subsequent output:
当然可以用 sed 做到这一点。例如,此命令返回后续输出:
sed '/NODE-ID> command1/!d;n;n;:a;/./!Q;n;ba' file
NODE-ID> command1
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
节点 ID> 命令 1
Lorem ipsum dolor sat amet,consectetuer adipiscing elit,sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat。Ut wisi enim ad minim veniam, quis nostrud exerciation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat。
回答by potong
This might work for you (GNU sed):
这可能对你有用(GNU sed):
sed '/NODE-ID> command1/!d;n;n;q' file
or:
或者:
awk '/command2/,/consequat/ {print awk '/command2/{st=NR;for(i=st;i<=st+6;i++){print ##代码##;getline}}' data.txt
}' data.txt
if the command only consists of one line of text (as per your example).
如果命令仅包含一行文本(根据您的示例)。
回答by Levon
If there was something unique in your last line of your records, such the string "consequat" in your sample data this simpleawkcommand would work:
如果您的记录的最后一行中有一些独特的东西,例如示例数据中的字符串“consequat”,这个简单的awk命令将起作用:
Alternatively, if the length of the records is going to be the same, then this will work:
或者,如果记录的长度相同,那么这将起作用:
##代码##In this example it will extract the block starting with command2and grab the next 6 lines (which works with the provided sample data set/format)
在这个例子中,它将提取块开始command2并抓取接下来的 6 行(适用于提供的样本数据集/格式)

