我可以根据前几个字符是否为空在前一行后附加一行吗?
例如,我在下面有数据:
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