reorganiza os dados com base em um padrão

3

Eu tenho um arquivo como este,

A1: abc.com B1: Hi there
B1: Your Test mail  A1: gml.com
B1: Your new mail   A1: hml.com
A1: def.com B1: Test email
B1: hello world A1: yml.com

Eu quero sempre escolher primeiro a parte A1: <string> , seguida da parte B1: <string> .

Eu tentei grep e awk como abaixo

 grep -Po '(?<=A1:)\W*\K[^ ]*' file.txt 
 awk -F"A1:|B1:" '{print $1 $2}' file.txt 

Mas eles não estão dando os resultados exatos

Eu quero que a saída seja assim:

 A1: abc.com   B1: Hi there
 A1: gml.com   B1: Your Test mail   
 A1: hml.com  B1: Your new mail 
 A1: def.com  B1: Test email
 A1: yml.com  B1: hello world
    
por user2340345 08.06.2018 / 08:40

2 respostas

4

Você pode deixar as linhas começando com A1 como está e reorganizar as que começam com B1

# if -E or -r is not supported: sed 's/\(B1:.*\)\(A1:.*\)/ /' ip.txt
$ sed -E 's/(B1:.*)(A1:.*)/ /' ip.txt
A1: abc.com B1: Hi there
A1: gml.com B1: Your Test mail  
A1: hml.com B1: Your new mail   
A1: def.com B1: Test email
A1: yml.com B1: hello world 
  • .* é ganancioso, portanto, esta solução assume que A1: e B1: são exclusivos em cada linha
  • (B1:.*)(A1:.*) são dois grupos de captura - para satisfazer a expressão inteira, o primeiro capturará todas as sequências de caracteres de B1: até pouco antes de A1: . O segundo capturará string de A1: até o final da linha
  • reorganizando as sequências capturadas com espaço entre
  • Outras leituras: link


Com awk

$ awk -F'A1:' '{print $1 ~ /B1:/ ? FS $2 " " $1 : $0}' ip.txt
A1: abc.com B1: Hi there
A1: gml.com B1: Your Test mail  
A1: hml.com B1: Your new mail   
A1: def.com B1: Test email
A1: yml.com B1: hello world 

Se o primeiro campo contiver B1: , reorganize os campos, caso contrário, imprima a linha de entrada como é

    
por 08.06.2018 / 08:43
0

Podemos fazer isso usando o seguinte método:

perl -F'/(A1:|B1:)/' -lane '
   my %h = @F[1..$#F];
   print map { "$_$h{$_} " } qw/A1: B1:/;
' input.txt

Saída:

A1: gml.com B1: Your Test mail   
A1: abc.com  B1: Hi there 
A1: hml.com B1: Your new mail    
A1: def.com  B1: Test email 
A1: yml.com B1: hello world

Explicação:

  • divida cada registro em A1: e / ou B1: mais inclua os "divisores" também.
  • o primeiro campo no array @F deve ser ignorado. portanto, há um número par de elementos no array @F que são então armazenados como um hash% h, com as chaves sendo "A1:" e "B1:".
  • Agora, iteramos pelo pedido prescrito por meio de uma matriz anônima, qw /.../ e imprimamos os resultados para stdout.
por 11.06.2018 / 11:22