Estrai una parte di una riga da un file con sed


18

Voglio leggere una parte di una riga da un file. Per esempio:

POP3_SERVER_NAME = localhost

Voglio tornare solo localhost, usando sed.

Questo testo è sulla terza riga. Faccio questo per estrarre la linea:

sed -n '3p' installation.sh

Come estraggo solo la localhostparte?

Risposte:


26

awk potrebbe essere uno strumento migliore qui.

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost

Cerca le righe che contengono "POP3_SERVER_NAME"; stampa l'ultimo campo. Questo non dipende dal fatto che POP3_SERVER_NAME sia sempre sulla linea 3, che è probabilmente una buona cosa.

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost

A seconda dell'applicazione, potrebbe essere necessario rendere l'espressione regolare più rigorosa. Ad esempio, potresti voler corrispondere solo a quella riga che inizia con POP3_SERVER_NAME.

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost

L'uso di sed è un po 'meno intuitivo. (Grazie, sono a conoscenza dell'ironia.) Indirizza la riga che contiene POP3_SERVER_NAME ovunque. Sostituisci una stringa vuota per tutto il testo dall'inizio della riga allo spazio opzionale che segue "=". Quindi stampa.

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat

2
Il awkcomando è carino, ma solo se hai spazi attorno a =. Non funzionerà per POP3_SERVER_NAME=localhost.
Marcel Stör

2
@Marcel, puoi cambiare il delimitatore usato dagli awkspazi in qualcos'altro usando -F. Ad esempio: -F "="verrà utilizzato =come delimitatore nel caso in cui si menziona.
Mattpr

7

Sostituisci il pcomando con una sostituzione che rimuove la parte indesiderata della linea.

sed -n '3 s/^[^=]*= *//p' installation.sh

Potresti voler abbinare la linea per parola chiave anziché per posizione.

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh

6

Sembra che tu abbia un file di configurazione. Quello che potresti fare è simile a quello che suggeriscono Adam Siemeon / slm:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename

dove [^=]esclude tutti '=' caratteri, +dice uno o più dello stesso tipo di carattere, questo segue un effettivo =, \squalsiasi spazio vuoto (comprese le linguette \te nuove linee \n, \r\n, e spazi semplici '', che *significa zero o più dello stesso tipo , le parentesi catturano ciò che c'è dentro per posizionare le sequenze di caratteri corrispondenti nei segnaposto sostitutivi \ 1, \ 2, ..., \ n, $significa la fine di una riga. Questo segue il tipico schema di sostituzione di:. s/.../.../modifiersL'opzione della riga di comando -rsta per sintassi regex estesa (per comodità) e -nsignifica che non viene emesso nulla fino a quando o se non richiesto esplicitamente. Il pmodificatore stampa il risultato.

È possibile effettuare una ricerca globale con il gmodificatore come:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1

in modo da ottenere una stringa separata da ' '(potrebbe essere \n, \to quel che avete), che è possibile elaborare facilmente.

Entrambi sono validi a condizione che i valori preceduti dall'equazione si estendano fino alla fine di una riga e non siano seguiti da commenti o altri caratteri con semantica che si discosti da un semplice "valore".


Modificare:

Non posso ancora commentare qui sui post degli altri. Per indicare la riga basta passare il numero della riga, nel tuo caso 3, prima so prima del carattere di quotazione iniziale (proprio come in vim).

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename

Per favore, dai un'occhiata info sed. Ad esempio, 3.2 e 4.7 sono di particolare interesse per te.


5
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost

O se hai i contenuti in un file:

sed 's/.*= //' somefile.txt
localhost

ok, ma ho letto nel mio file in questo modo: sed -n '3p' installation.sh
Mercer

2
@Mercer: vedi gli aggiornamenti che ho aggiunto alla risposta.
slm

@Adam Siemion - grazie, ma come indicare il numero di riga?
Mercer,

4

Puoi usare il comando cut, impostando il delimitatore su '=' e quindi stampare il secondo campo in questo modo:

cut -d'=' -f2

3

Molteplici modi per farlo, considerando che il tuo file si chiama foobar:

Specifica il modello da cercare:

PAT=POP3_SERVER_NAME

Estrai usando sed

sed -n "/$PAT/p" foobar | sed "s/$PAT = //"

O usando sedecut

sed -n "/$PAT/p" foobar | cut -d' ' -f3

2

Il bello di Linux / Unix è che di solito c'è più di un modo per realizzare qualcosa. Nel caso dell'operazione, ci sono almeno quattro modi diversi per estrarre il nome del server POP dal file:

  1. grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
  2. grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
  3. grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
  4. sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh
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.