Usando o GNU sed
, você pode fazer isso como:
sed -Ee '
s/^/\n\n/
s/\n\n/&\n/;s/[[:blank:]]+/\n/3;s/(.*)\n\n(.*)\n(.*)\n/\n\n/
s|<_0:MsgUID>|\n|;s|</_0:MsgUID>|\n|;s/(.*)\n\n(.*)\n(.*)\n/ \n\n/
s|<LoginName>|\n|;s|</LoginName>|\n|;s/(.*)\n\n(.*)\n(.*)\n/ \n\n/
s|<_1:CustId>|\n|;s|</_1:CustId>|\n|;s/(.*)\n\n(.*)\n(.*)\n/ \n\n/
s/\n\n.*//
' log.file
Explicação
- Colocamos um marcador,
\n\n
, no início da linha. Todas as correspondências encontradas na linha são lançadas para a esquerda deste marcador.
- Primeiro, isolamos a parte da data e, em seguida, movemo-la para a esquerda do marcador.
- Em todas as etapas subsequentes, isolamos as tags de interesse e lançamos os valores da tag à esquerda do marcador.
- Quando terminamos, simplesmente apagamos tudo à direita do marcador, incluindo o marcador, e o que resta no espaço padrão é o que queremos.
- Observação: esse método é extensível para incluir quantas tags forem necessárias.
Resultados
03 Jun 2017/13:51:32:553 20150103135132968917 Userid 12345678
Outra maneira é usar os regexes Perl:
perl -lne '$,=$";
print /^(?:\S+\s+){2}\S+|<(?:_0:MsgUID|LoginName|_1:CustId)>\K(?:.*?)(?=<)/g' log.file
Aqui, definimos a OFS
$,
para $"
, que é space
. O perl regex /..../g
produzirá todas as correspondências não parecidas em uma lista, que então será o espaço impresso separado devido ao valor do OFS já estabelecido.