Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sed 如何根据相邻行的第一个字段是否为空来连接它们?_Sed_Awk_Text Parsing_Reformat - Fatal编程技术网

Sed 如何根据相邻行的第一个字段是否为空来连接它们?

Sed 如何根据相邻行的第一个字段是否为空来连接它们?,sed,awk,text-parsing,reformat,Sed,Awk,Text Parsing,Reformat,我是否可以根据前几个字符是否为空,在前一行后面追加一行 例如,我有以下数据: zone: z_ABCSVR01_STORAGE1 ABCSVR; STORAGE1_P1; STORAGE_P2 zone: z_SUNSVR1_NBUSANCP SUNSVR1; NBUSANCP; zone: z_WINSVR01_STORAGE2 WINSVR01; STORAGE1_P2;

我是否可以根据前几个字符是否为空,在前一行后面追加一行

例如,我有以下数据:

zone:  z_ABCSVR01_STORAGE1
                ABCSVR; STORAGE1_P1;
        STORAGE_P2  
zone:  z_SUNSVR1_NBUSANCP
                SUNSVR1; NBUSANCP;
zone:  z_WINSVR01_STORAGE2
                WINSVR01; STORAGE1_P2;
        STORAGE_P3
我需要下面的输出:

z_ABCSVR01_STORAGE1 ABCSVR; STORAGE1_P1;    STORAGE_P2                      
z_SUNSVR1_NBUSANCP  SUNSVR1; NBUSANCP;               
z_WINSVR01_STORAGE2 WINSVR01; STORAGE1_P2;  STORAGE_P3     
使用awk

awk '{printf (/^zone/)?RS $0:FS $0}' file

zone:  z_ABCSVR01_STORAGE1                 ABCSVR; STORAGE1_P1;         STORAGE_P2
zone:  z_SUNSVR1_NBUSANCP                 SUNSVR1; NBUSANCP;
zone:  z_WINSVR01_STORAGE2                 WINSVR01; STORAGE1_P2;         STORAGE_P3

如果需要删除无用的空白:

awk '{printf (/^zone/)?RS $0:FS $0}' file|awk '$1=$1'

zone: z_ABCSVR01_STORAGE1 ABCSVR; STORAGE1_P1; STORAGE_P2
zone: z_SUNSVR1_NBUSANCP SUNSVR1; NBUSANCP;
zone: z_WINSVR01_STORAGE2 WINSVR01; STORAGE1_P2; STORAGE_P3
使用awk

awk '{printf (/^zone/)?RS $0:FS $0}' file

zone:  z_ABCSVR01_STORAGE1                 ABCSVR; STORAGE1_P1;         STORAGE_P2
zone:  z_SUNSVR1_NBUSANCP                 SUNSVR1; NBUSANCP;
zone:  z_WINSVR01_STORAGE2                 WINSVR01; STORAGE1_P2;         STORAGE_P3

如果需要删除无用的空白:

awk '{printf (/^zone/)?RS $0:FS $0}' file|awk '$1=$1'

zone: z_ABCSVR01_STORAGE1 ABCSVR; STORAGE1_P1; STORAGE_P2
zone: z_SUNSVR1_NBUSANCP SUNSVR1; NBUSANCP;
zone: z_WINSVR01_STORAGE2 WINSVR01; STORAGE1_P2; STORAGE_P3

如果您有
GNU awk
,这里还有另一种方法:

$ awk -v RS='zone:' '$1=$1' file
z_ABCSVR01_STORAGE1 ABCSVR; STORAGE1_P1; STORAGE_P2
z_SUNSVR1_NBUSANCP SUNSVR1; NBUSANCP;
z_WINSVR01_STORAGE2 WINSVR01; STORAGE1_P2; STORAGE_P3

如果您有
GNU awk
,这里还有另一种方法:

$ awk -v RS='zone:' '$1=$1' file
z_ABCSVR01_STORAGE1 ABCSVR; STORAGE1_P1; STORAGE_P2
z_SUNSVR1_NBUSANCP SUNSVR1; NBUSANCP;
z_WINSVR01_STORAGE2 WINSVR01; STORAGE1_P2; STORAGE_P3
在连接线时也删除空白


在连接行时也删除空白

如果
GNU awk
可用,@jaypal简洁而优雅的解决方案就是最好的选择

这里有一个符合POSIX标准的解决方案,它试图在i和t之间打点(导致@jaypal的解决方案不符合标准的原因是使用了一个包含多个(文字)字符的
RS
(记录分隔符)值):

  • 它根据OP的请求从输出中删除
    区域:
  • 它不会在开头打印额外的
    \n
    ,也不会省略后面的一个
  • 它使用带有格式参数的
    printf
    安全地避免意外的控制字符。输入行中的扩展

如果
GNU awk
可用,@jaypal简洁而优雅的解决方案就是一条出路

这里有一个符合POSIX标准的解决方案,它试图在i和t之间打点(导致@jaypal的解决方案不符合标准的原因是使用了一个包含多个(文字)字符的
RS
(记录分隔符)值):

  • 它根据OP的请求从输出中删除
    区域:
  • 它不会在开头打印额外的
    \n
    ,也不会省略后面的一个
  • 它使用带有格式参数的
    printf
    安全地避免意外的控制字符。输入行中的扩展
这可能适用于您(GNU-sed):

这可能适用于您(GNU-sed):


要删除空白,请执行以下操作:
awk'{$1=$1;printf(/^zone/)?RS$0:FS$0}'文件
,该命令适用于关键字
/^zone/
。但如果遵循规则,如
前几个字符为空
,则无法删除空白。对于关键字
/^zone/
,此命令可以执行:
awk'{$1=$1;printf(/^zone/)?RS$0:FS$0}'文件
。但如果遵循规则,因为
前几个字符是空的
,它就不能解释
NR>1的用法是什么<代码>AWK-V RS=“区域”:“$ 1=1美元”文件< CygWin,在我的Env(CygWin)中,我没有看到空白行。“代码是正确的,<代码> { 1美元=1美元} 1 < /代码>将打印空白行,但是<代码> $1=$1 < /COD>不这样,因为它也隐含在布尔上下文中,如<代码> $1 {$1=$1;打印} <代码>(这是我的理解)。@AdrianFrühwirth谢谢,我不知道他的评论没有包括牙套。固定的!为了解释这一美妙之处:
RS='zone:'
在出现
zone:
之间,跨行将输入分解为记录
$1=$1
触发基于OFS
的每个输入记录的重建(输出字段分隔符,默认为单个空格)-这就是合并行和(也将多个空格折叠为一个)的原因;在输出时,记录由ORS分隔,ORS默认为
\n
。请参阅@AdrianFrühwirth的评论,了解为什么(根据需要)在开始时不打印空行,即使输入以
区域开始:
(因此处理的第一条记录是空的)。
NR>1
有何用途<代码>AWK-V RS=“区域”:“$ 1=1美元”文件< CygWin,在我的Env(CygWin)中,我没有看到空白行。“代码是正确的,<代码> { 1美元=1美元} 1 < /代码>将打印空白行,但是<代码> $1=$1 < /COD>不这样,因为它也隐含在布尔上下文中,如<代码> $1 {$1=$1;打印} <代码>(这是我的理解)。@AdrianFrühwirth谢谢,我不知道他的评论没有包括牙套。固定的!为了解释这一美妙之处:
RS='zone:'
在出现
zone:
之间,跨行将输入分解为记录
$1=$1
触发基于OFS的每个输入记录的重建(输出字段分隔符,默认为单个空格)-这就是合并行和(也将多个空格折叠为一个)的原因;在输出时,记录由ORS分隔,ORS默认为
\n
。请参阅@AdrianFrühwirth的评论,了解为什么(根据需要)在开始时不打印空行,即使输入以
区域开始:
(因此处理的第一条记录为空)。 awk ' { if ($1=="zone:") { # Zone lines # Determine the separator to *precede* the output line: # ORS, the output *record* separator, which defaults to \n # - unless it is the very first line. # Net effect: zone lines start new output lines. sep=(notFirst++ ? ORS : ""); # Remove the `zone:` field by setting the first field, # $1, to an empty string. # Note: This causes the entire line to be rebuilt by joining the # fields with OFS, the output field separator, which defaults # to a space. Multiple adjacent space chars. are folded into # one in the process. $1=""; # Remove the space char. at the beginning of the rebuilt # line that stems from setting $1 to an empty string. $0=substr($0,2) } else { # Non-zone lines # Determine the separator to *precede* the output line: # just the regular output *field* separator (space), # effectively causing this line to be appended to the # previous one. sep=OFS; # Trigger rebuilding the line so as to fold # multiple adjacent space chars. into one. $1=$1; } # Output the separator followed by the rebuilt line. printf "%s%s", sep, $0 } # Since the `printf` statement above never outputs # a *terminating* \n, we output one at the very end. END { print } ' file
sed ':a;$!N;/\nzone:/!s/\n\s*/ /;ta;s/^zone:\s*//;P;D' file