GNU/Linux >> Linux Esercitazione >  >> Linux

Come analizzare XML e rimuovere i tag usando gli esempi XPATH in Linux (Come combinare più comandi usando PIPE in Linux)

Questo tutorial spiega il processo di creazione di utili comandi multiparte pezzo per pezzo.

Per creare comandi complessi nel terminale, è necessario comprendere il piping. Il piping sta fondamentalmente prendendo l'output di un comando e inviandolo a un altro comando come input. Questo viene fatto con | simbolo (tubo).

Il mese scorso, un piccolo progetto mi ha richiesto di leggere ripetutamente file XML simili per fornire dati di test per un altro programma. Dovrei farlo così frequentemente che sarebbe fastidioso dover scaricare, salvare, analizzare e ripetere. I requisiti di base erano:

  1. Ottieni XML dall'URL
  2. Analizza l'XML e seleziona solo due attributi di tutti gli elementi
  3. Togli i tag in modo che rimanga solo il contenuto
  4. Invia a output standard

1. Dimostra che la riga di comando può analizzare XML

Avevo usato la libreria Ruby REXML::Xpath per uno script l'anno scorso e mi sono ricordato che c'era una versione Perl disponibile sulla riga di comando. Puoi installarlo con CPAN:

$ cpan XML::XPath

Usiamo un file di esempio del dipendente per giocare con l'idea. Apri questo file employee.xml in un browser, aprilo in un browser e salvalo come employee.xml.

Ora abbiamo il nostro comando xpath e un file con cui giocare.

Provalo con un percorso semplice:

$ xpath employees.xml '/DIRECTORY/EMPLOYEE/FIRST_NAME'
­­ NODE ­­
<FIRST_NAME>Steven</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Susan</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Marigold</FIRST_NAME>­­ NODE ­­
...
<FIRST_NAME>Sunny</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Flo</FIRST_NAME>

Eccellente! Stampa l'attributo FIRST_NAME di ogni /EMPLOYEE sul percorso selezionato. Ma come selezioniamo più elementi XPath? Osservando la sintassi di XPath, vediamo un modo. Combinando le espressioni XPath con il | carattere, creiamo un'espressione OR.

$ xpath employees.xml '/DIRECTORY/EMPLOYEE/ FIRST_NAME | /DIRECTORY/EMPLOYEE/LAST_NAME'
--­­ NODE ­­--
<FIRST_NAME>Steven</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Sanguini</LAST_NAME>­--­ NODE ­--­
<FIRST_NAME>Susan</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Aquilegia</LAST_NAME>--­­ NODE --­­
...
<FIRST_NAME>Flo</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Lobalessia</LAST_NAME>

Avviso, qui | viene interpretato come l'operatore OR e non il reindirizzamento dell'output.

Inoltre, in questa affermazione, selezioniamo X oltre a Y. Perché OR seleziona entrambi? Valuta ogni nodo nel documento XML separatamente e se il nodo è A o B, passa la valutazione e viene passato all'output.

2. Scarica XML e invia a STDOUT

Questo passaggio successivo verrà effettivamente prima sulla riga di comando e lo costruiremo separatamente. Preferisco creare prima le voci di comando più difficili o "non puoi farlo" come prova del concetto. Sarebbe inutile eseguire il lavoro della riga di comando circostante se il passaggio uno non può funzionare.

cURL è un potente comando per le interazioni HTTP. Questi esempi di ricci ti faranno iniziare nella giusta direzione.

Specifichiamo una posizione, seguendo i reindirizzamenti se necessario. Per questo, usa questa opzione:-L ‘https://www.thegeekstuff.com/scripts/employees.xml’

Disattiviamo l'output delle informazioni di cURL. E specificare il protocollo GET. Per questo, usa questa opzione:-s G

Quindi proviamo il nostro comando sull'URL del file che abbiamo scaricato in precedenza:

$ curl -­s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml'
<?xml version="1.0" encoding="UTF­8"?>
<DIRECTORY>
<EMPLOYEE>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>Sanguini</LAST_NAME>
<STORE_NUMBER>4</STORE_NUMBER>
<SHIFT>FIRST</SHIFT>
<AUM>$2.44</AUM>
<ID>031599</ID>
</EMPLOYEE>
..

Il valore predefinito è STDOUT. Il che è positivo poiché ora lo reindirizzeremo a XPath rimuovendo l'argomento del file:

$ curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | xpath \
'/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID'
­--­ NODE ­­--
<LAST_NAME>Sanguini</LAST_NAME>­­-- NODE ­­--
<ID>031599</ID>­­ NODE ­­
<LAST_NAME>Aquilegia</LAST_NAME>­­-- NODE -- ­­
<ID>030699</ID>­­-- NODE ­­--
...
<LAST_NAME>Lobalessia</LAST_NAME>--­­ NODE --­­
<ID>022299</ID>

Questo produce l'output atteso. Grande! Non sono sicuro del perché, ma XPath invia "NODE" all'errore standard (STDERR). Ma vedremo un possibile motivo più avanti.

3. Elimina i tag XML

Ora dobbiamo essere in grado di rimuovere quei tag e ottenere solo il contenuto. Sed è lo strumento migliore per eseguire sostituzioni al volo di espressioni regolari. Imparare REGEX non rientra nell'ambito di questo articolo.

Per ulteriori informazioni, consulta la nostra serie di articoli sulle espressioni regolari Python.

Quando creo comandi complicati con più argomenti e flag, trovo che sia meglio lavorare con un semplice esempio finché non lo ottengo nel modo giusto, quindi incollarlo nel contesto con gli argomenti reali. Conduciamo una semplice stringa su sed per una sostituzione di test. Sed funziona su STDIN per impostazione predefinita.

$ echo "This<strong> is </strong>a test." | sed ­-re 's/i//g'
Ths<strong> s </strong>a test.

Ok. Che funzioni. Ora riscrivi la ricerca per sostituire un tag.

$ echo "This<strong> is </strong>a test." | sed ­-re 's/<\w+>//g'
This is </strong>a test.

Bene. Rimuoviamo il tag di chiusura aggiungendo '/' escape preceduto da '\' e reso opzionale dal suffisso '?'

$ echo "This<strong> is </strong>a test." | sed ­re 's/<\/?\w+>//g'
This is a test.

Perfetto. Esattamente quello che ci aspettavamo.

4. Mettere tutto insieme

Ora che abbiamo creato le singole parti del nostro comando, le incolliamo insieme in ordine logico uniti da | .

curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | \
xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID ' | \
sed ­-re 's/<\/?\w+>//g'

Uscita:

Found 72 nodes:
--­­ NODE -- ­­
­--­ NODE ­­--
...
Sanguini031599Aquilegia030699...

Uh Oh! Forse è per questo che ci sono i marcatori "NODO". Se lo inviamo in un file, il testo NODE non segue. Vengono inviati all'errore standard (STDERR), ma possiamo reindirizzare a STDOUT usando `2>&1` (spiegazione) e usare il sostituto sed `sed re 's/ NODE //g'` per eseguire lo strip nello stesso modo del tag.

curl -­s -­G -­L 'https://www.thegeekstuff.com/scripts/employees.xml' | \
xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID '
2>&1| sed -­re 's/­--­NODE--­­//g' | sed -­re 's/<\/?\w+>//g'

Uscita:

Found 72 nodes:
Sanguini
031599
Aquilegia
030699
...
Lobalessia
022299

Perfetto. Ora, mentre lavoro al mio progetto, posso ottenere rapidamente dati di esempio da file XML sul Web a STDOUT senza il fastidio di salvare file o eseguire software complicati. Possiamo persino reindirizzare questo a `tail –n+3` per tagliare quelle prime due linee di risposta.

Questo articolo è solo un esempio delle varie cose che puoi fare se impari a combinare più comandi usando pipe.


Linux
  1. Come trasferire file tra due computer utilizzando i comandi nc e pv

  2. Come utilizzare i comandi "cat" e "tac" con esempi in Linux

  3. Comandi Linux - Panoramica ed esempi

  4. Controlla lo spazio su disco in Linux usando df e du Commands

  5. Comandi Head and Tail in Linux spiegati con esempi

Come eseguire comandi dall'input standard utilizzando Tee e Xargs in Linux

Come visualizzare i cheatsheet dei comandi di Linux usando ad es

Come utilizzare i comandi Pbcopy e Pbpaste su Linux

Come eseguire il backup di file e directory utilizzando Rsync in Linux

Come eseguire app Linux su Windows 10 e 11 utilizzando WSL

Come eseguire più comandi Linux in un unico comando