我有一个文件如下.数据块以区域开始,在一行线之后总是有一个水平的空白区域,一个空行.
zone name Z_ZEBRA_TIGER vsan 900
* fcid 0x801e00 [device-alias TEST]
* fcid 0x3d8b40 [device-alias TIGER1]
* fcid 0x3d8bc0 [device-alias TIGER2]
* fcid 0x3d8b60 [device-alias CAT]
zone name Z_chili_yahoo vsan 100
* fcid 0x801400 [device-alias chilli]
* fcid 0x803500 [device-alias yahoo]
zone name Z_tom_tommy vsan 100
* fcid 0x801400 [device-alias toma]
pwwn 0x803460 [device-alias tommya]
Run Code Online (Sandbox Code Playgroud)
我想打印如下 - 从区域字开始直到空白行将线转换为并排打印.
zone name Z_ZEBRA_TIGER vsan 900 * fcid 0x801e00 [device-alias TEST] * fcid 0x3d8b40 [device-alias TIGER1] * fcid 0x3d8bc0 [device-alias TIGER2] * fcid 0x3d8b60 [device-alias CAT]
zone name Z_chili_yahoo vsan 100 * fcid 0x801400 [device-alias chilli] * fcid 0x803500 [device-alias yahoo]
zone name Z_tom_tommy vsan 100 * fcid 0x801400 [device-alias toma] pwwn 0x803460 [device-alias tommya]
Run Code Online (Sandbox Code Playgroud)
我尝试使用tr,没有运气.有人可以帮忙吗?通过sed或awk实现这一目标的任何简单方法.
$ awk -v RS="" -F'\n' -v OFS=" " '{$1=$1;print}' foo.txt
zone name Z_ZEBRA_TIGER vsan 900 * fcid 0x801e00 [device-alias TEST] * fcid 0x3d8b40 [device-alias TIGER1] * fcid 0x3d8bc0 [device-alias TIGER2] * fcid 0x3d8b60 [device-alias CAT]
zone name Z_chili_yahoo vsan 100 * fcid 0x801400 [device-alias chilli] * fcid 0x803500 [device-alias yahoo]
zone name Z_tom_tommy vsan 100 * fcid 0x801400 [device-alias toma] pwwn 0x803460 [device-alias tommya]
Run Code Online (Sandbox Code Playgroud)
-v RS=""
使用空行作为记录分隔符.
-F'\n'
使用换行作为输入的字段分隔符.
-v OFS=" "
在输出中使用空格作为字段分隔符.
$1=$1
这将第一个字段设置为等于它自己.这具有发信号通知线路已被改变的效果,这将导致awk在输出时用新的字段分隔符替换旧的字段分隔符.
print
打印记录.
正如约翰所指出的那样,可以缩短形式.首先,因为输出字段分隔符默认是空格,所以我们不需要显式设置它.其次,可以使用隐含的print.因此,上述命令在功能上等同于:
awk -v RS="" -F'\n' '{$1=$1}1' foo.txt
Run Code Online (Sandbox Code Playgroud)
$ sed ':a;N;$!ba; s/\n/ /g; s/ zone name/\nzone name/g' foo.txt
zone name Z_ZEBRA_TIGER vsan 900 * fcid 0x801e00 [device-alias TEST] * fcid 0x3d8b40 [device-alias TIGER1] * fcid 0x3d8bc0 [device-alias TIGER2] * fcid 0x3d8b60 [device-alias CAT]
zone name Z_chili_yahoo vsan 100 * fcid 0x801400 [device-alias chilli] * fcid 0x803500 [device-alias yahoo]
zone name Z_tom_tommy vsan 100 * fcid 0x801400 [device-alias toma] pwwn 0x803460 [device-alias tommya]
Run Code Online (Sandbox Code Playgroud)
这会立即读取整个文件.如果输入文件很大(对于内存来说太大),请使用awk解决方案.
:a;N;$!ba;
这会立即读取整个文件.
s/\n/ /g;
这将用空格替换所有换行符.
s/ zone name/\nzone name/g
这会在短语出现之前添加换行符zone name.