awk para combinar e recortar campos com delimitador alternativo

3

Gostariadeusarawkousemelhanteparacorresponderaospadrõesdeumarquivodemarcadoreschromee,dependendodacorrespondência,recortarumcampoespecíficocombaseemdiferentesdelimitadoresdecampo.

Anexeiumafotodeamostra.Euaindanãodescobricomoanexarcomoumarquivo,porfavor,tenhapaciênciacomigo.

EuqueroosnomesdaspastascasoastringH3sejacorrespondidaeaURLcasoastringHREFsejaencontrada.

osdoiscomandosseguintesfazemotrabalhodasrespetivascorrespondências:

awk-F'[<>]''/H3/{print$5}'bookmarks.htmawk-F'"' '/HREF/{print $2}' bookmarks.html

Meu objetivo é combinar as duas instruções acima para que a saída se torne:

UNIX
url-1
url-2
OCE
url-3
url-4
url-5
ANDROID
url-6
url-7

Eu tentei awk se, então, mas não foi conclusivo.

Como faço para isso como um one-liner? há melhores candidatos do que awk ? python, perl seria ótimo, no entanto, o one-liner é um absoluto, pois seria uma tarefa fácil escrever um script de shell que faz o trabalho.

    
por HenrikJson 19.02.2017 / 22:14

4 respostas

2

Esta é uma maneira incorreta de processar arquivos html com sed / awk /… Existem poucos analisadores especiais, mas como substituição temporária

sed '
    /\n/{P;d;}
    /<H3/s/[><]/\n/4g
    /HREF/s/"/\n/g
    D
    ' bookmarks.htm

Para versões não-GNU de sed :

sed '
    /\n/{P;d;}     #if there is more then 1 line «P»rint 1st line then «d»elete all
    /<\/H3/s//\n/  #replace «</H3» by «\n»ewline
    /\n/s/">/\n/   #replace «">» by «\n»ewline if previous command is executed
    /HREF/s/"/\n/g #put «\n»ewline» around url if «HREF» in line
    D              #«D»elete 1 first line, go to start
    ' bookmarks.htm
    
por 19.02.2017 / 22:53
1

Usar um analisador / processador xml / html tem algumas vantagens. Expressões Xpath são a maneira padrão de selecionar partes específicas.

xml + xmlstarlet + xpath

Se a entrada for bem formada xml, podemos usar xmlstarlet + xpath expression:

xmlstarlet sel -t -v '//h3|//a/@href' -nl bookmarks.html

html + xmllint: xml

Se a entrada for apenas html válida, podemos convertê-la em xml (usando xmllint ) e usar a anterior:

xmllint -html -xmlout ex.html | xmlstarlet sel -t -v '//h3|//a/@href' -nl -

xmllint + xpath

Podemos usar a expressão xmllint + xpath diretamente

xmllint -html -xpath '//h3/text()|//a/@href' bookmarks.html

... mas o formato de saída não é o mesmo ...

    
por 20.02.2017 / 01:17
1

Uma última resposta: desta vez um perl ligner

perl -nE 'say $1 if (/<h3.*?>(.*?)<\/h3>/i or /href="(.*?)"/i)' ex.html

(Acredito que as soluções baseadas em analisador xml são melhores, mas como você tem um arquivo gerado por ferramenta, a quantidade de surpresas não deve ser muito alta)

    
por 21.02.2017 / 09:27
0

Por enquanto eu descartei a demanda por uma linha e fiz isso como um script.

Eu tive que postar isso como uma resposta, pois teria sido muito longo para um comentário. Ainda assim, sinta-se à vontade para responder.

Este script faz o trabalho, mas é muito lento, alguém pode acelerar ou, em alternativa, sugerir um one-liner?

#!/bin/sh
file=$1
while IFS= read -r line
do
hdr=$(echo $line | awk -F'[<>]' '/H3/{print $5}')
url=$(echo $line | awk -F'"' '/HREF/{print $2}')
if [ ${url} ]; then
    echo $url
elif [ ${hdr} ]; then
    echo $hdr
fi
done <"$file"

Aqui o arquivo: (finalmente entendi)

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
  <h1>Bookmarks</h1>
  <dl>
    <dd>
        <DT><H3 ADD_DATE="1484311924" LAST_MODIFIED="1485532328">UNIX</H3>
      <dl>
        <dt><a HREF="http://unix.stackexchange.com/questions/223182/how-to-replace-spaces-in-all-file-names-with-underscore-in-linux-using-shell-scr" add_date="1484311897">url-1</a></dt>
        <dt><a HREF="http://unix.stackexchange.com/questions/81349/how-do-i-use-find-when-the-filename-contains-spaces"        add_date="1484738308">url-2</a></dt>
      </dl>
    </dd>
    <dd>
        <DT><H3 ADD_DATE="1486550854" LAST_MODIFIED="1487228526">OCE</H3>
      <dl>
        <dt><a HREF="http://www.oraclecertificationprep.com/apex/f?p=OCPSG%3AEXAM_DETAILS%3A%3A%3ANO%3A%3AP2_EXAM%3A1Z0-061"    add_date="1486550866">url-3</a></dt>
        <dt><a HREF="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=303&amp;p_certName=SQ1Z0_047" add_date="1486550898">url-4</a></dt>
        <dt><a HREF="https://www.quora.com/How-do-you-prepare-for-an-Oracle-Database-SQL-exam" add_date="1486550950">url-5</a></dt>
      </dl>
    </dd>
    <dd>
        <DT><H3 ADD_DATE="1487084050" LAST_MODIFIED="1487228595">ANDROID</H3>
      <dl>
        <dt><a HREF="https://material.io/guidelines/style/color.html#" add_date="1487228526">url-6</a></dt>
        <dt><a HREF="https://developer.android.com/index.html" add_date="1487228539">url-7</a></dt>
      </dl>
    </dd>
  </dl>
</body>
</html>  
    
por 20.02.2017 / 22:59