processamento de texto: extrai partes de um arquivo e grava-as em uma única linha

1

Eu tenho vários arquivos formatados assim:

...
<title> Field1 : DATA_FIELD_1</title>
...
<i class="blablabla"></i> <b>Field2 : </b> <span>DATA_FIELD_2</span>
...
<i class="blablabla"></i> <b>Field3 : </b> <span>DATA_FIELD_3</span>
...
<i class="blablabla"></i> <b>Field4 : </b> <span>DATA_FIELD_4</span >
...
<i class="blablabla"></i> <b>Field5 : </b> <span>DATA_FIELD_5 </span>
...

Eu gostaria de ler cada arquivo e obter os dados de cada campo e gravá-los em um novo arquivo em um formato separado por pipe.

Por exemplo:

FileID | Field1 | Field2 | Field3 | Field4 | Field5
1 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5
2 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5
3 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5
4 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5

i consegui extrair os dados indevidamente com o grep usando o comando:

grep -o 'Field1 : .*\|Field2 : .*\|Field3 : .*\|Field4 : .*\|Field5 : .*' File-* >> NewFile

mas este é o resultado que recebo

File-1:Field1 : DATA_FIELD_1</title>
File-1:Field2 : </b> <span>DATA_FIELD_2</span>
File-1:Field3 : </b> <span>DATA_FIELD_3</span>
File-1:Field4 : </b> <span>DATA_FIELD_4</span >
File-1:Field5 : </b> <span>DATA_FIELD_5 </span>
File-2:Field1 : DATA_FIELD_1</title>
File-2:Field2 : </b> <span>DATA_FIELD_2</span>
File-2:Field3 : </b> <span>DATA_FIELD_3</span>
File-2:Field4 : </b> <span>DATA_FIELD_4</span >
File-2:Field5 : </b> <span>DATA_FIELD_5 </span>
File-3:Field1 : DATA_FIELD_1</title>
File-3:Field2 : </b> <span>DATA_FIELD_2</span>
File-3:Field3 : </b> <span>DATA_FIELD_3</span>
File-3:Field4 : </b> <span>DATA_FIELD_4</span >
File-3:Field5 : </b> <span>DATA_FIELD_5 </span>
    
por user223423 29.03.2017 / 22:42

2 respostas

0

Geralmente, é uma má ideia processar HTML / XML com expressões regulares porque elas não são expressivas o suficiente para lidar com todos os casos de canto. No entanto, a saída do seu grep sugere que podemos no seu caso preciso.

Aqui está uma maneira de processar a saída que você obtém do comando grep com sed:

sed -e 'N;N;N;N;s/^File-\(.*\):Field1 : \(.*\)<\/title>.*Field2 : .*<span>\(.*\)<\/span *>.*Field3 : .*<span>\(.*\)<\/span *>.*Field4 : .*<span>\(.*\)<\/span *>.*Field5 : .*<span>\(.*\)\s*<\/span *>/ |  |  |  |  | /'

Explicações:

  • N;N;N;N; : isso é usado para unir as linhas cinco por cinco (para ter todos os campos de um arquivo na mesma linha)
  • s/ : isso inicia um comando de substituição, a primeira parte é a correspondência, a segunda é a substituição
  • ^File-\(.*\): : corresponde ao número do arquivo
  • Field1 : \(.*\)<\/title> : corresponde ao primeiro campo
  • .*Field2 : .*<span>\(.*\)<\/span *> : corresponde ao segundo
  • ...
  • / | | / | | / : esta é a parte de substituição: cada grupo delimitado por \(.*\) na primeira parte é capturado e reutilizável através de variáveis especiais , , etc.

Resultado:

1 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5 
2 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5 
3 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5
    
por 29.03.2017 / 23:40
0

Outra abordagem possível é usar um processador XML. Neste caso, XMLstarlet.

xmlstarlet sel -t -v 'substring-after(//title,":")' \
                  -m //span -o "|" -v .  \
               -t -n  *.xml

Onde:

  • sel -t - selecione peças XML de acordo com o seguinte modelo
  • -v 'substring-after(//title,":")' - é o valor do título depois de ":"
  • -m //span -o "|" -v . - corresponde a span e imprime "|" e seu valor
  • -t -n - adicione uma nova linha
por 01.04.2017 / 11:38