$ awk -v RS='(^|\n)zone' '/\n[^*]/ { print "zone" $0 }' input
zone name tommy
* pwwn xxxxxxxx
pwwn xyzabcda
* pwwn xcvuytnm
zone name angelfalls
* pwwn xxxxxxxx
pwwn xyzabcda
zone name Newyork
* pwwn xxxxxxxx
pwwn xyzabcda
Este script awk define o Separador de Registros ( RS ) como o início do arquivo de entrada ou uma nova linha, seguido pela palavra "zona". Em seguida, imprime cada "registro" que contém pelo menos uma nova linha não seguida por * .
Ele precisa imprimir a palavra "zone" junto com $0 porque awk automaticamente remove o RS de cada registro de entrada.
NOTA: Como RS não é apenas uma nova linha por si só, $0 contém as novas linhas no final de cada linha de entrada (isso está intimamente relacionado ao motivo mencionado acima para saber por que a "zona" precisa ser impresso). Isso significa que haverá uma linha extra em branco no final da saída. Se isso for um problema, a maneira mais fácil de se livrar dele é com sed . por exemplo,
awk -v RS='(^|\n)zone' '/\n[^*]/ { print "zone" $0 }' input | sed '$d'
Por fim, se o pwwn for uma parte importante dos critérios de correspondência, altere a correspondência de expressão regular no script de /\n[^*]/ para /\n[^*] pwwn/ . (com a entrada de exemplo fornecida, a saída é idêntica, mas pode diferir com sua entrada real muito maior)