$ tr '}' '\n' <file | sed -E 's/^ ?\{//'
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
Isso primeiro substitui cada } por uma nova linha usando tr . Isso dá ao comando sed linhas individuais para trabalhar, onde cada linha começará com um espaço possível e um { . Esses caracteres são removidos do início da linha pelo comando sed .
A mesma coisa com apenas sed :
sed -E -e 's/ ?\{//g' -e 'y/}/\n/'
O comando y funciona como tr neste exemplo.
Usando o GNU awk ou mawk , mas não o BSD awk :
$ awk -v RS='[{}]' '/[^[:blank:]]/' file
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
Isso interpreta os dados como registros separados por { ou } e, em seguida, imprime cada registro que contém algo diferente de guias ou espaços.
Usando o Perl:
$ perl -ne 'map { print "$_\n" } /{(.*?)}/g' file
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
Isso aplica um comando print a cada elemento retornado pela correspondência da expressão regular dada com a entrada. O comando print também acrescenta uma nova linha a cada elemento para obtê-los em linhas individuais.