将新行转换为由空行分隔的文本块中的空白

1 unix awk sed

我有一个文件如下.数据块以区域开始,在一行线之后总是有一个水平的空白区域,一个空行.

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)

我想打印如下 - 从区域字开始直到空白行将线转换为并排打印.

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实现这一目标的任何简单方法.

Joh*_*024 6

使用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

$ 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.