Linux 根据格式分批从文件中删除Grep行

Linux 根据格式分批从文件中删除Grep行,linux,unix,awk,sed,grep,Linux,Unix,Awk,Sed,Grep,我有一个文件,内容如下: 您好,欢迎光临!区块开始第1行第2行!区块开始第1行第2行第3行!区块开始第1行第2行第3行第1行第2行第3行第4行第5行第1行第2行第3行第4行 现在,以“!Chunk Start”开头且在下一个“!Chunk Start”之前的所有内容都是块,即“!Chunk Start”之间的行构成块。我需要在一行中获取每个块的内容。i、 e: 第1行第2行第1行第2行第3行第1行第2行第3行第1行第2行第3行第4行第5行第1行第2行第3行第4行 我已经这样做了,但我认为应该有更

我有一个文件,内容如下:

您好,欢迎光临!区块开始
第1行
第2行
!区块开始
第1行
第2行
第3行
!区块开始
第1行
第2行
第3行
第1行
第2行
第3行
第4行
第5行
第1行
第2行
第3行
第4行

现在,以“!Chunk Start”开头且在下一个“!Chunk Start”之前的所有内容都是块,即“!Chunk Start”之间的行构成块。我需要在一行中获取每个块的内容。i、 e:

第1行第2行第1行第2行第3行第1行第2行第3行第1行第2行第3行第4行第5行第1行第2行第3行第4行

我已经这样做了,但我认为应该有更好的办法。我这样做的方式是:

grep-A100“!Chunk Start”file.txt

剩下的逻辑是用来连接这些行的。但这是我担心的A100。如果一个块中有100多行,这将失败。 我可能需要使用awk/sed来完成此操作。请建议。

您可以使用GNU AWK(
gawk
)。它有一个GNU扩展,用于将输入除以
!区块开始
。然后,您的每一行“块”都可以作为一个字段进行处理。标准AWK对字段的数量有限制(99或更多?),但是。这么多的字段应该可以解决您对每个块100多行输入的担忧

$ gawk 'BEGIN{RS="! Chunk Start\n";FS="\n"}NR>1{$1=$1;print}' infile.txt
AWK(和gnuawk)的工作原理是将输入划分为记录,然后将每个记录划分为字段。这里,我们根据字符串
划分记录(记录分隔符
RS
)!区块开始
,然后根据换行符将每条记录划分为字段(字段分隔符
FS
)。您还可以指定自定义输出记录分隔符
ORS
和自定义输出字段分隔符
OFS
,但在这种情况下,我们希望的是默认值(
ORS=“\n”
OFS=“

当划分为记录时,第一个
之前的部分!区块开始
将被视为记录。我们使用
NR>1
忽略这一点。我已经解释了你的问题说明

以“!Chunk Start”开头且在下一个“!Chunk Start”之前的所有内容都是块

意思是说曾经
!Chunk Start
已被看到,在输入结束之前的所有内容都至少属于某个Chunk

神秘的
$1=$1
强制
gawk
重新处理输入行
$0
,该行使用输入格式(
FS
)解析它,使用换行符。
print
使用输出格式(
OFS
ORS
)打印此重新处理的行

编辑:上面的版本在每行末尾打印空格。感谢@EdMorton指出默认字段分隔符
FS
在空格(包括换行符)上分隔,因此
FS
应该保持不变:

$ gawk 'BEGIN{RS="! Chunk Start\n"}NR>1{$1=$1;print}' infile.txt
您可以使用GNUawk(
gawk
)。它有一个GNU扩展,用于将输入除以
!区块开始
。然后,您的每一行“块”都可以作为一个字段进行处理。标准AWK对字段的数量有限制(99或更多?),但是。这么多的字段应该可以解决您对每个块100多行输入的担忧

$ gawk 'BEGIN{RS="! Chunk Start\n";FS="\n"}NR>1{$1=$1;print}' infile.txt
AWK(和gnuawk)的工作原理是将输入划分为记录,然后将每个记录划分为字段。这里,我们根据字符串
划分记录(记录分隔符
RS
)!区块开始
,然后根据换行符将每条记录划分为字段(字段分隔符
FS
)。您还可以指定自定义输出记录分隔符
ORS
和自定义输出字段分隔符
OFS
,但在这种情况下,我们希望的是默认值(
ORS=“\n”
OFS=“

当划分为记录时,第一个
之前的部分!区块开始
将被视为记录。我们使用
NR>1
忽略这一点。我已经解释了你的问题说明

以“!Chunk Start”开头且在下一个“!Chunk Start”之前的所有内容都是块

意思是说曾经
!Chunk Start
已被看到,在输入结束之前的所有内容都至少属于某个Chunk

神秘的
$1=$1
强制
gawk
重新处理输入行
$0
,该行使用输入格式(
FS
)解析它,使用换行符。
print
使用输出格式(
OFS
ORS
)打印此重新处理的行

编辑:上面的版本在每行末尾打印空格。感谢@EdMorton指出默认字段分隔符
FS
在空格(包括换行符)上分隔,因此
FS
应该保持不变:

$ gawk 'BEGIN{RS="! Chunk Start\n"}NR>1{$1=$1;print}' infile.txt
这可能适用于您(GNU-sed):

删除最多包含
的第一行!区块开始
。收集行,用空格替换换行符。找到下一个匹配项后,打印第一行,删除图案空间并重复。

这可能适合您(GNU-sed):


删除最多包含
的第一行!区块开始
。收集行,用空格替换换行符。找到下一个匹配项后,打印第一行,删除图案空间并重复。

好的。只需使用awk:

$ awk -v RS='! Chunk Start' '{$1=$1}NR>1' file
Line 1 Line2
Line 1 Line 2 Line 3
Line 1 Line 2 Line 3 Line 1 Line 2 Line 3 Line 4 Line 5 Line 1 Line 2 Line 3 Line 4

以上使用GNU awk进行多字符RS。

好的。只需使用awk:

$ awk -v RS='! Chunk Start' '{$1=$1}NR>1' file
Line 1 Line2
Line 1 Line 2 Line 3
Line 1 Line 2 Line 3 Line 1 Line 2 Line 3 Line 4 Line 5 Line 1 Line 2 Line 3 Line 4

上面使用GNU awk进行多字符RS。

这对我来说很好。谢谢。你能解释一下命令吗?这可能比我的
gawk
版本更干净。在GNU
sed
中似乎也存在一些问题。我不确定这个特殊的
sed
命令的可移植性,但是
gawk
通常是我必须手动安装的东西,因为它并没有全部随附