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



我可以根据前几个字符是否为空在前一行后附加一行吗?

例如,我在下面有数据:

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     

如果您有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

使用 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 (/^[[:space:]]/)?FS $0:RS $0}' file

如果您需要删除无用的空格:

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
sed -n '1h;1!H;${x;s/n  *//g;p;}' YourFile

连接行时也删除空格

如果GNU awk可用,@jaypal简洁优雅的解决方案是要走的路。

这是一个符合 POSIX 的解决方案,它尝试点缀 i 并交叉 t(使 @jaypal 的解决方案不合规的原因是使用了包含多个(文字)字符的 RS(记录分隔符)值):

  • 它根据OP的要求从输出中删除zone:
  • 它不会在开头打印额外的n或省略尾随的。
  • 它安全地使用带有格式参数的printf,以避免输入行中的意外控制字符扩展。
awk '{      if ($1=="zone:") { sep=(notFirst++ ?ORS : ");$1=";$0=子链($0,2) }      else { sep=OFS; $1=$1; }      printf "%s%s", 九月, $0     }       结束 { 打印 }    ' 文件

这是同一程序的大量注释版本,希望能解释此处使用的awk更神秘的功能:

哎呀'  {    如果 ($1=="区域:") { # 区域行                   # 确定分隔符以*在*输出行之前:        # ORS,输出 *记录* 分隔符,默认为         # - 除非它是第一行。        # 净效应:区域线开始新的输出线。      sep=(notFirst++ ?ORS : ");        # 通过设置第一个字段删除"区域:"字段,        # $1,为空字符串。        # 注意:这会导致整条生产线通过加入        # 带有 OFS(输出字段分隔符)的字段,默认为        # 到空格。多个相邻空格字符被折叠成        # 一个在过程中。      $1=";        # 在重建开始时删除空格字符        # 行,源自将 $1 设置为空字符串。      $0=子链($0,2)    } else { # 非区域行        # 确定分隔符以*在*输出行之前:        # 只是常规输出 *字段* 分隔符(空格),        # 有效地导致此行附加到        # 前一个。      九月=OFS;        # 触发重建线以便弃牌        # 多个相邻空格字符合二为一。      $1=$1;    }         # 输出分隔符,后跟重建的行。    printf "%s%s", 九月, $0  }    # 因为上面的 'printf' 语句从不输出    # a *终止* ,我们在最后输出一个。  结束 { 打印 }  ' 文件

这可能对你有用(GNU sed):

sed ':a;$!N;/nzone:/!s/ns*/ /;ta;s/^zone:s*//;P;D' file

相关内容

  • 没有找到相关文章

最新更新