unix - Convert new lines to blanks within blocks of text separated by empty lines -


i have file below. block of data starts zone , after block of lines there horizontal white space, blank line.

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] 

i want print below — starting zone word till blank line convert line print side side.

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] 

i tried using tr, no luck. can please? easy way achieve via sed or awk.

using 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] 

how works

  • -v rs=""

    use blank line record separator.

  • -f'\n'

    use newline field separator on input.

  • -v ofs=" "

    use space field separator on output.

  • $1=$1

    this sets first field equal itself. has effect of signaling line has been changed , cause awk replace old field separators new ones upon output.

  • print

    print record.

short form

as jotne points out, possible make shorter form. first, because output field separator is, default, space, don't need set explicitly. secondly, possible use implicit print. thus, above command functionally equivalent to:

awk -v rs="" -f'\n' '{$1=$1}1' foo.txt 

using 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]  

this reads whole file in @ once. if input file huge (too big memory), use awk solution.

how works

  • :a;n;$!ba;

    this reads whole file in @ once.

  • s/\n/ /g;

    this replaces newlines spaces.

  • s/ zone name/\nzone name/g

    this puts newline in front of occurrence of phrase zone name.


Popular posts from this blog