在两个模式之间组合多条线



在HP-Unix上: 输入文件如下所示:

BEGIN_BLOCK
random_line1
random_line_2
END_BLOCK
junk lines...
BEGIN_BLOCK
random_line1
random_line2
random_line3
END_BLOCK
and so on ..

期望输出:

BEGIN_BLOCK random_line1 random_line_2 END_BLOCK
BEGIN_BLOCK random_line1 random_line2 random_line3 END_BLOCK

基本上,将BEGIN_BLOCKEND_BLOCK之间的所有行放在一行中。

注意:文本BEGIN_BLOCKEND_BLOCK不会出现在random_lines中。 我是一个新手,不太弄清楚如何使awk产生此输出。

您可以使用单个变量相对简单地执行此操作,以跟踪您是否在块中,您应该在其中输出当前记录并将其附加到当前行,或者如果您在块之间(不在块中),您应该跳过打印记录。

您可以使用三个规则,第一个规则在/^BEGIN_BLOCK/输出记录、设置inblock=1和跳到下一条记录时触发。第二个只是测试是否设置了inblock,如果是,则将记录附加到当前输出行,最后在遇到/^END_BLOCK/时触发规则,您可以在其中完成输出行并设置inblock=0

例如:

awk -v inblock=0 '
/^BEGIN_BLOCK/  { printf "%s", $0; inblock=1; next }
inblock         { printf " %s", $0 }
/^END_BLOCK/    { printf "n"; inblock=0 }
' file

(注意:您使用printf而不是print,因此您可以进行下线控制,选择何时不输出以及何时输出'n'END_BLOCK规则可以简单地print ""哪个是等效的)

示例使用/输出

使用file中的示例输入,您可以选择复制和鼠标中键将上述内容粘贴到包含file的目录中的 xterm 中,并获得:

$ awk -v inblock=0 '
>     /^BEGIN_BLOCK/  { printf "%s", $0; inblock=1; next }
>     inblock         { printf " %s", $0 }
>     /^END_BLOCK/    { printf "n"; inblock=0 }
> ' file
BEGIN_BLOCK random_line1 random_line_2 END_BLOCK
BEGIN_BLOCK random_line1 random_line2 random_line3 END_BLOCK

你可以用一种更精简、更难读的方式写这个——几种不同的方式。您可以使用字符串串联来构建包含BEGIN_BLOCKEND_BLOCK之间的所有信息的单个字符串,并且只需输出一次,而不是将每条记录附加到输出行等。在awk中剥猫皮的许多不同的方法。

例如,使用字符串串联,您可以执行以下操作:

awk -v inblock=0 '
/^BEGIN_BLOCK/  { inblock=1 }
inblock         { s=(length(s) ? s" "$0 : $0) }
/^END_BLOCK/    { print s; s=""; inblock=0 }
' file

(相同的输出 - 但请注意,所有字符串连接都发生在inblock规则中)

但是,如果您有空BEGIN_BLOCKEND_BLOCK行或BEGIN_BLOCKEND_BLOCK出现故障的行怎么办?然后,您的输出会将它们全部连接在一起。您始终可以通过添加其他逻辑(以小步骤)来优化awk脚本以处理其他注意事项。例如:

awk -v inblock=0 '
/^BEGIN_BLOCK/  { inblock=1 }
inblock         { s=(match($0,/BEGIN_BLOCK/) ? $0 : s" "$0) }
/^END_BLOCK/    { if (inblock && s != "BEGIN_BLOCK END_BLOCK") print s; s=""; inblock=0 }
' file

仅当BEGIN_BLOCKEND_BLOCK之间有其他行时,并且仅在开始和结束BEGIN_BLOCKEND_BLOCK标记之间打印输出。它将处理一个可怕的混乱和无序file例如:

$ cat file
BEGIN_BLOCK
random_line1
random_line_2
END_BLOCK
junk lines...
BEGIN_BLOCK
END_BLOCK
END_BLOCK
END_BLOCK
BEGIN_BLOCK
stuff_in_bad_begin
BEGIN_BLOCK
random_line1
random_line2
random_line3
END_BLOCK
...

如果你只是在学习awk,请参阅 StackOverflow AWK 标签信息和我最喜欢的 GNU Awk 用户指南

如果您有其他问题,请告诉我。

另一个尴尬,

awk ' /BEGIN_BLOCK/,/END_BLOCK/ { printf("%s ",$0); next } { print "" } END { print "" } '
$ cat manoj.txt
BEGIN_BLOCK
random_line1
random_line_2
END_BLOCK
junk lines...
BEGIN_BLOCK
random_line1
random_line2
random_line3
END_BLOCK
$ awk ' /BEGIN_BLOCK/,/END_BLOCK/ { printf("%s ",$0); next } { print "" } END { print "" } ' manoj.txt
BEGIN_BLOCK random_line1 random_line_2 END_BLOCK
BEGIN_BLOCK random_line1 random_line2 random_line3 END_BLOCK
$

您可以将其管道传输到另一个awk并删除空白行。

awk ' /BEGIN_BLOCK/,/END_BLOCK/ { printf("%s ",$0); next } { print "" } END { print "" } ' manoj.txt | awk 'NF'

最新更新