Reordene o texto em cada linha de um arquivo

2

Estou processando um arquivo de log e preciso reordenar cada linha (não classificar). O arquivo de log é assim:

11-06-2014 - 10:49:06PM lat = 41.858657; lon = -91.345142
11-06-2014 - 10:49:49PM lat = 42.864653; lon = -92.349914
11-06-2014 - 10:50:35PM lat = 43.874808; lon = -93.350364
11-06-2014 - 10:51:21PM lat = 44.885047; lon = -94.350058
11-06-2014 - 10:52:08PM lat = 45.895078; lon = -95.349920
11-06-2014 - 10:53:30PM lat = 46.905178; lon = -96.349837
11-06-2014 - 10:54:50PM lat = 47.910303; lon = -97.350606

e quero mover a data / hora para o final de cada linha:

lat = 41.858657; lon = -91.345142 11-06-2014 - 10:49:06PM
lat = 42.864653; lon = -92.349914 11-06-2014 - 10:49:49PM
lat = 43.874808; lon = -93.350364 11-06-2014 - 10:50:35PM
lat = 44.885047; lon = -94.350058 11-06-2014 - 10:51:21PM
lat = 45.895078; lon = -95.349920 11-06-2014 - 10:52:08PM
lat = 46.905178; lon = -96.349837 11-06-2014 - 10:53:30PM
lat = 47.910303; lon = -97.350606 11-06-2014 - 10:54:50PM

sed? awk? como?

Pergunta bônus: meu objetivo final é transformar isso em gpx / xml, e provavelmente é tão fácil adicionar o texto intermediário à medida que cada linha é processada, para que a saída seja assim:

<wpt lat="41.858657" lon="-91.345142">
    <time>11-06-2014 - 10:49:06PM</time>
</wpt>

<wpt lat"="42.864653" lon="-92.349914">
     <time>11-06-2014 - 10:49:49PM</time>
</wpt>

<wpt lat"="43.874808" lon="-93.350364">
     <time>11-06-2014 - 10:50:35PM</time>
</wpt>

<wpt lat"="44.885047" lon="-94.350058">
     <time>11-06-2014 - 10:51:21PM</time>
</wpt>

<wpt lat"="45.895078" lon="-95.349920">
     <time>11-06-2014 - 10:52:08PM</time>
</wpt>

<wpt lat"="46.905178" lon="-96.349837">
     <time>11-06-2014 - 10:53:30PM</time>
</wpt>

<wpt lat"="47.910303" lon="-97.350606">
     <time>11-06-2014 - 10:54:50PM</time>
</wpt>
    
por Robert Altman 07.11.2014 / 17:57

5 respostas

5

usando o awk:

 awk '{print $4,$5,$6,$7,$8,$9,$1,$2,$3}' log_file

você pode fazer isso diretamente do seu arquivo de log assim:

awk '{printf("<wpt %s%s\"%s\" %s%s\"%s\">\n<time>%s %s %s</time>\n</wpt>\n",$4,$5,substr($6,0,length($6)),$7,$8,$9,$1,$2,$3)}' log_file

saída:

<wpt lat="41.858657" lon="-91.345142">
<time>11-06-2014 - 10:49:06PM</time>
</wpt>
<wpt lat="42.864653" lon="-92.349914">
<time>11-06-2014 - 10:49:49PM</time>
</wpt>
<wpt lat="43.874808" lon="-93.350364">
<time>11-06-2014 - 10:50:35PM</time>
</wpt>
<wpt lat="44.885047" lon="-94.350058">
<time>11-06-2014 - 10:51:21PM</time>
</wpt>
<wpt lat="45.895078" lon="-95.349920">
<time>11-06-2014 - 10:52:08PM</time>
</wpt>
<wpt lat="46.905178" lon="-96.349837">
<time>11-06-2014 - 10:53:30PM</time>
</wpt>
<wpt lat="47.910303" lon="-97.350606">
<time>11-06-2014 - 10:54:50PM</time>
</wpt>
    
por 07.11.2014 / 18:23
4

Você pode usar

perl -lane 'print "@F[2..$#F] $F[0] $F[1]"' log_file

para inverter as linhas de registro.

    
por 07.11.2014 / 18:23
2
sed '   s/ *[=;]"* */="/g;s//" /2         #first sub-out spaces; for "
        s|\(.*M\) \(.*\)|\                #then do the replace
<wpt ">\
        <time></time>\
</wpt>|
' <<\INPUT
11-06-2014 - 10:49:06PM lat = 41.858657; lon = -91.345142
11-06-2014 - 10:49:49PM lat = 42.864653; lon = -92.349914
11-06-2014 - 10:50:35PM lat = 43.874808; lon = -93.350364
11-06-2014 - 10:51:21PM lat = 44.885047; lon = -94.350058
11-06-2014 - 10:52:08PM lat = 45.895078; lon = -95.349920
11-06-2014 - 10:53:30PM lat = 46.905178; lon = -96.349837
11-06-2014 - 10:54:50PM lat = 47.910303; lon = -97.350606
INPUT

Isso é o que eu criei. É bastante simples em sed . Eu uso caracteres literais aqui porque é mais fácil para mim ler e porque nem todos os sed irão lidar com escapes de barra invertida no campo de substituição do lado direito. Se o seu fizer, então sinta-se livre. De qualquer forma, definitivamente esses comentários inline vão estragar qualquer sed , então remova-os antes do teste.

OUTPUT

<wpt lat="41.858657" lon="-91.345142">
        <time>11-06-2014 - 10:49:06PM</time>
</wpt>

<wpt lat="42.864653" lon="-92.349914">
        <time>11-06-2014 - 10:49:49PM</time>
</wpt>

<wpt lat="43.874808" lon="-93.350364">
        <time>11-06-2014 - 10:50:35PM</time>
</wpt>

<wpt lat="44.885047" lon="-94.350058">
        <time>11-06-2014 - 10:51:21PM</time>
</wpt>

<wpt lat="45.895078" lon="-95.349920">
        <time>11-06-2014 - 10:52:08PM</time>
</wpt>

<wpt lat="46.905178" lon="-96.349837">
        <time>11-06-2014 - 10:53:30PM</time>
</wpt>

<wpt lat="47.910303" lon="-97.350606">
        <time>11-06-2014 - 10:54:50PM</time>
</wpt>
    
por 07.11.2014 / 22:05
1

a primeira parte do seu rearranjo pode ser feita facilmente, contanto que a composição dos dados seja a mesma e não mude.

cat myfile | while read line
do
  latlong=$(echo ${line} | cut -d " " -f 4-)
  datetime=$(echo ${line} | cut -d " " -f 1-3)
  echo ${latlong}" "${datetime} >> mynewlyformattedfile
done

isso pode ser feito de forma mais elaborada em uma linha, usando sed e / ou awk, tenho certeza, mas tentei fazer isso dessa forma para mostrar o que está acontecendo em que ponto.

usando o comando cut , você pode extrair qualquer parte de uma linha e fazer eco com qualquer prefixo / sufixo para criar seu arquivo xml facilmente na minha opinião.

    
por 07.11.2014 / 18:19
1

O mesmo que para sed

sed -E 's&(.*M)( .*);( .*)$&<wpt>\n\t<time></time>\n</wpt>&;
        $!G;
        s& = ([-.0-9]+)&=""&g' log.file

Ou coloque-o no arquivo de script

#!/bin/sed -Ef
s|(.*M)( .*);( .*)$|<wpt>\n\t<time></time>\n</wpt>|
$!G
s| = ([-.0-9]+)|=""|g

E use-o

sed -Ef script.file log.file

ou se executou por chmod +x ./script.file apenas

./script.file log.file
    
por 07.11.2014 / 20:12