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

我需要下面的输出:

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

5 回答 5

4

如果您有,这是另一种方法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
于 2014-04-01T03:38:38.163 回答
2

Using 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

or

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

If you need remove useless white space:

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
于 2014-04-01T03:26:14.123 回答
0

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

sed ':a;$!N;/\nzone:/!s/\n\s*/ /;ta;s/^zone:\s*//;P;D' file
于 2014-04-01T06:51:07.267 回答
0
sed -n '1h;1!H;${x;s/\n  *//g;p;}' YourFile

加入行时也删除空格

于 2014-04-01T06:01:52.507 回答
0

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

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

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

下面是同一个程序的一个被大量评论的版本,希望能解释awk这里使用的更神秘的特性:

啊啊啊
  {
    if ($1=="zone:") { # 区域线            
        # 确定 *precede* 输出行的分隔符:
        # ORS,输出*record*分隔符,默认为\n
        # - 除非它是第一行。
        # 净效应:区域线开始新的输出线。
      sep=(notFirst++ ? ORS : "");
        # 通过设置第一个字段来移除 `zone:` 字段,
        # $1, 到一个空字符串。
        # 注意:这会导致整条线路通过加入
        # 带 OFS 的字段,输出字段分隔符,默认值
        # 到一个空格。多个相邻的空格字符。被折叠成
        # 一个在进程中。
      $1="";
        # 删除空格字符。在重建之初
        # 源于将 $1 设置为空字符串的行。
      $0=substr($0,2)
    } else { # 非区域行
        # 确定 *precede* 输出行的分隔符:
        # 只是常规输出 *field* 分隔符(空格),
        # 有效地导致这一行被附加到
        # 前一个。
      九月=OFS;
        # 触发重建线以便折叠
        # 多个相邻的空格字符。合而为一。
      $1=$1;
    }    
      # 输出分隔符后跟重建的行。
    printf "%s%s", 九月, $0
  }
    # 因为上面的 `printf` 语句从不输出
    # a *terminating* \n,我们在最后输出一个。
  结束{打印}
  ' 文件
于 2014-04-01T06:27:35.590 回答