In un articolo precedente, ho spiegato come manipolare il testo con grep
. Ora rivolgi la tua attenzione al sed
(Stream Editor), che è più adatto per essere utilizzato nelle pipeline (dati provenienti da una pipe). Il sed
l'utilità può essere utilizzata per stampare il contenuto di un file, sostituire una riga (o più righe) e quindi salvare il file. In contrasto con grep
, sed
può sostituire una o più righe in un file ed eseguire un sul posto aggiornamento di quel file.
Il più semplice sed
invocazione durante la sostituzione di foo
per bar
è:
$ sed 's/foo/bar/' inputfile
Esempio:rimuovere i commenti
Mentre grep
può formattare l'output sullo schermo, non è in grado di modificare un file sul posto. Per fare ciò, avresti bisogno di un editor di file come ed
. Da ed
non fa parte di questo articolo, usa sed
per ottenere la stessa cosa che hai fatto con grep
nel primo esempio dell'articolo precedente. Questa volta modifica il /etc/fstab
file sul posto passando il -i
segnala a sed
. Senza il -i
flag , vedresti solo ciò che sarebbe stato modificato.
Ti invitiamo a eseguire sempre sed
senza il -i
flag, solo per assicurarsi che il risultato che produce sia previsto. Il sed
l'utilità offre anche il -i.bak
flag, che crea un file di backup prima della modifica.
Il grep
finale il comando per questo esempio era:
$ grep -v '^#' /etc/fstab > ~/fstab_without_comment
Con sed
, hai:
# sed -i '/^#/d' /etc/fstab
/dev/mapper/VGCRYPTO-ROOT / ext4 defaults,x-systemd.device-timeout=0 1 1
UUID=e9de0f73-ddddd-4d45-a9ba-1ffffa /boot ext4 defaults 1 2
LABEL=SSD_SWAP swap swap defaults 0 0
Esempio:solo stampa /etc/passwd
utenti
Nel grep
ad esempio, hai stampato solo i nomi utente da /etc/passwd
file con quanto segue:
$ grep -Eo '^[a-zA-Z_-]+' /etc/passwd
Puoi fare lo stesso usando sed
come segue:
$ sed 's/^\([a-zA-Z_-]\+\).*/\1/' /etc/passwd
Nell'esempio sopra, raggruppi una corrispondenza tra parentesi ()
, quindi stampa il gruppo corrispondente con \1
(back-reference), che detta il primo gruppo. Per un secondo gruppo, utilizzeresti \2
, e così via.
Esempio:sostituisci tutto foo
con bar
In sed
, puoi cercare un pattern e quindi sostituire solo l'occorrenza corrispondente al pattern. Per sostituire tutte le occorrenze nel file inputfile1
da foo
a bar
a livello globale, esegui:
$ sed -i '/foo/bar/g' inputfile1
Esempio:sostituisci una singola istanza
Prendi il file inputfile2
, che ha i seguenti contenuti:
hello world
second line should be replaced
this line should be replaced later
Supponi di voler sostituire should
con will
, ma solo per la seconda riga. Questo comando è suddiviso come segue:
$ sed '/second/s/should/will/' inputfile2
| | | |
| | | with this pattern
| | this pattern
| substitute
Search for the pattern "second"
Questo output viene inviato all'output standard anziché sostituire il contenuto del file. Il risultato è simile al seguente:
$ sed '/second/s/should/will/' inputfile2
hello world
second line will be replaced
this line should be replaced later
Il sed
il comando fa distinzione tra maiuscole e minuscole. Quanto segue non funzionerà quando proverai a sostituire World
con there
:
$ echo "Hello World" | sed 's/world/there/'
Hello World
GNU sed
introdotto un nuovo flag, /I
, che ignora il caso e lo farà eseguire la sostituzione con lo stesso comando:
$ echo "Hello World" | sed 's/world/there/I'
Hello there
Esempio:stampa un intervallo di righe ed esci
Con sed
, puoi anche stampare righe e uscire dopo aver soddisfatto i tuoi criteri. I seguenti comandi stamperanno tre righe e chiuderanno. Questo comando:
$ sed -n '1,3p' /etc/passwd
equivale a:
$ sed '3q' /etc/passwd
Sarebbe sbagliato:
$ sed '1,3q' /etc/passwd # Wrong. You cannot quit three times
Esempio:commentare le righe non commentate
Le espressioni regolari possono essere utilizzate anche con sed
, come dimostrato in precedenza. Ad esempio, hai il seguente piccolo script:
$ cat test_script
#/usr/bin/env bash
this is the first comment
This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Ora devi saltare la prima riga, che inizia con #!/bin/bash
e commenta la terza e la quarta riga, ma non la quinta perché quella riga è già commentata.
In sed
, puoi utilizzare qualcosa come il seguente:
$ sed '3,6s/^[^#]/# &/g' test_script
#/usr/bin/env bash
# this is the first comment
# This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Nel comando precedente, viene eseguito quanto segue:
3,6s
definisce un intervallo, dalla riga tre fino alla riga sei./^[^#]/
corrisponde a tutto ciò che è un carattere e non inizia con un hash (#
)./# &/g
sostituisce una parte, in questo caso inserisce un#
davanti alla riga dettata da&
firmare.
Esempio:rimuovi tutte le cifre
Diverse applicazioni generano dati in diversi formati. Con sed
, puoi conservare solo i dati che puoi utilizzare. Ad esempio, hai il seguente file (inputfile3
) in questo formato:
foo1234
bar99128
baz2842
qux12953
discard39120
Forse un programma ha generato il formato sbagliato o ha concatenato i campi a uno. E se fossi interessato solo a mantenere i caratteri alfa e volessi scartare le cifre? Come raggiungeresti questo obiettivo con sed
?
La risposta è probabilmente più facile di quanto pensi:
$ sed 's/\([a-z]*\).*/\1/' inputfile3
foo
bar
baz
qux
discard
Esempio:modifica righe specifiche
Inoltre, sed
può anche gestire intervalli in base al modello, il che significa che puoi specificare un inizio e una fine stringa e manipolare l'intervallo. Ad esempio:
$ cat inputfile4
hello world
start of the comment
another comment
end of a comment
dont comment this line
nor this line
Il seguente sed
il comando commenterà le righe che iniziano con inizio e termina con fine :
$ sed '/start/,/end/ s/^/# /' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
Sbarazzati anche delle righe vuote.
$ sed '/start/,/end/ s/^/# /;/^$/d' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
C'è molto di più da sed
e le sue ricche caratteristiche. Per poter utilizzare pienamente sed
abilità di , si prega di consultare la sua pagina di documentazione, che puoi trovare qui. Inoltre, un'ottima fonte di informazioni su sed
può essere trovato qui.
Concludi
Come ho spiegato in precedenza, utilizzerai grep
quando si desidera cercare un modello, in un file o in più directory in modo ricorsivo. Usa sed
se stai ricevendo dati da una pipeline o desideri manipolare i dati al volo.
Il sed
il comando è programmato ed è facile imparare a eseguire operazioni di base. Tutto ciò di cui hai bisogno è esercitarti, specialmente con le espressioni regolari.