我有一个文件如下。 数据块以区域开头,在一行线之后总是有一个水平的空格,一个空行。
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]
我想将其打印如下 - 从区域字开始直到空白行将该行转换为并排打印。
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]
我尝试使用tr,没有运气。有人可以帮忙吗? 通过sed或awk实现这一目标的任何简单方法。
答案 0 :(得分:6)
$ 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]
-v RS=""
使用空行作为记录分隔符。
-F'\n'
使用换行作为输入的字段分隔符。
-v OFS=" "
在输出中使用空格作为字段分隔符。
$1=$1
这将第一个字段设置为等于它自己。这会产生信号表明线路已被更改的效果,这将导致awk在输出时用新的字段分隔符替换旧的字段分隔符。
print
打印记录。
正如约翰所指出的那样,可以缩短形式。首先,因为输出字段分隔符默认是空格,所以我们不需要显式设置它。其次,可以使用隐式print
。因此,上述命令在功能上等同于:
awk -v RS="" -F'\n' '{$1=$1}1' foo.txt
$ 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]
这会立即读取整个文件。如果输入文件很大(对于内存来说太大),请使用awk解决方案。
:a;N;$!ba;
这会立即读取整个文件。
s/\n/ /g;
这将用空格替换所有换行符。
s/ zone name/\nzone name/g
这会在短语zone name
出现之前添加换行符。
答案 1 :(得分:0)
sed -n '/^$/!{H;$!b
}
s/.*//;x;s/.//;s/\n/ /g;p' YourFile
-n
:仅按需打印/^$/!
:如果不是白线
H
:将行附加到缓冲区。$!b
如果不是文件的结尾(最后一行),请对脚本进行循环处理(使用下一行重启)s/.*//;x
;清空当前行并将其与缓冲区交换s/.//;s/\n/ /g
:删除第一个字符(第一个追加的新行)并将所有新行更改为空格p
:打印结果并循环到下一行答案 2 :(得分:0)
Perl:
perl -00 -nE 's/\n/ /g; say' foo.txt
-00
一次读取文件