Come posso elaborare i record multilinea con awk in uno script bash?


13

esempio.txt è sotto

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

Sto usando bash script e diciamo che voglio cercare un ristorante con il suo nome dal file sopra. Chiedere all'utente di inserire il nome del ristorante e dovrebbe stampare le informazioni relative a quel ristorante (5 righe).

awk '/McDonalds/> /KFC/' example.txt

So che la riga di codice sopra stamperà l'intera riga che corrisponde allo schema "McDonalds" e "KFC" ma che stamperà solo la prima riga dal file di testo ma non il resto delle informazioni su quel ristorante. Come posso dirgli di stampare tutte le informazioni (5 righe) solo dall'input dell'utente del nome del ristorante?

Risposte:


11

Con awk, è possibile modificare il separatore dei record . Per impostazione predefinita è una nuova riga, quindi ogni riga del file è un record. Se imposti la RSvariabile su una stringa vuota, awk considererà i record separati da righe vuote:

awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt

Non capisco la tua domanda. È abbastanza vago. È il compito o l'uso che non ottieni?
Glenn Jackman,

3

Utilizzando sed:

$ sed -n '/KFC/,/^$/p' file
Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

$ sed -n '/McDo/,/^$/p' file
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Spiegazione

Questa è la sedfunzione di base , è possibile fare riferimento a SCRIP DI UNA LINEA UTILI PER SED

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive

Aggiungi la spiegazione
BMW

Ma perché la modifica suggerita è stata respinta? Non ho cambiato la risposta. Ho appena migliorato la formattazione.
margherita

2
$ awk '$2=="KFC" {print; for(i=1; i<=4; i++) { getline; print}}' example.txt

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

Il comando sopra ottenere e stampare le successive 4 righe insieme alla linea corrente perché è stato alimentato in un modello di ricerca per loop.The $2=="KFC"si aiuta ad ottenere una linea particolare dalle linee multiple.


0

Un'altra possibile soluzione:

awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt

È {if($1=="KFC")print $0}possibile condensare a solo $1 == "KFC", poiché l'azione predefinita per una condizione vera è stampare il record.
muru,

0

È sufficiente stampare dalla riga contenente il nome desiderato, all'ultima riga contenente la parola Phone(presupponendo ovviamente che tutte le voci seguano lo stesso modello e avranno sempre Phonecome record di chiusura)

$> awk '/5 guys/,/Phone/' restaurants.txt                                     
Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911
$> awk '/McDonalds/,/Phone/' restaurants.txt                                  
Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Se volessimo complicarlo un po ', potremmo stampare esattamente 5 righe dopo la partita, in questo modo:

awk '/McDonalds/{stop=NR+5}; NR<=stop ' restaurants.txt                    

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

La stopvariabile non verrà impostata, quindi NR<=stopnon stamperà nulla, fino /McDonalds/{stop=NR+5;}a quando la parte non imposta effettivamente la variabile, e ciò avverrà solo quando troveremo la corrispondenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.