Di seguito verrà stampata la corrispondenza della riga TERMINATE
fino alla fine del file:
sed -n -e '/TERMINATE/,$p'
Spiegazione: -n
disabilita il comportamento predefinito sed
di stampa di ogni riga dopo aver eseguito il suo script su di essa, -e
indicato uno script su sed
, /TERMINATE/,$
è una selezione di intervallo di indirizzi (riga) che significa che la prima riga che corrisponde TERMINATE
all'espressione regolare (come grep) alla fine del file ( $
) ed p
è il comando di stampa che stampa la riga corrente.
Questo verrà stampato dalla riga che segue la corrispondenza della riga TERMINATE
fino alla fine del file:
(da DOPO la riga corrispondente a EOF, NON compresa la riga corrispondente)
sed -e '1,/TERMINATE/d'
Spiegazione: 1,/TERMINATE/
è una selezione dell'intervallo di indirizzi (riga) che indica la prima riga per l'input alla prima riga corrispondente TERMINATE
all'espressione regolare, ed d
è il comando di eliminazione che elimina la riga corrente e passa alla riga successiva. Poiché sed
il comportamento predefinito è di stampare le righe, le righe verranno stampate dopo TERMINATE
fino alla fine dell'input.
Modificare:
Se vuoi le linee prima TERMINATE
:
sed -e '/TERMINATE/,$d'
E se vuoi entrambe le righe prima e dopo TERMINATE
in 2 file diversi in un unico passaggio:
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
I file before e after conterranno la riga con terminate, quindi per elaborare ciascuno devi usare:
head -n -1 before
tail -n +2 after
Edit2:
Se non si desidera codificare i nomi dei file nello script sed, è possibile:
before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
Ma poi devi sfuggire al $
significato dell'ultima riga in modo che la shell non proverà ad espandere la $w
variabile (nota che ora usiamo le virgolette doppie attorno allo script invece delle virgolette singole).
Ho dimenticato di dire che la nuova riga è importante dopo i nomi dei file nella sceneggiatura, in modo che sed sappia che i nomi dei file finiscono.
Modifica: 30/05/2016
Sébastien Clément ha chiesto: "Come sostituiresti l'hardcoded TERMINATE
con una variabile?"
Dovresti creare una variabile per il testo corrispondente e farlo allo stesso modo dell'esempio precedente:
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
utilizzare una variabile per il testo corrispondente con gli esempi precedenti:
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
I punti importanti sulla sostituzione del testo con variabili in questi casi sono:
- Le variabili (
$variablename
) racchiuse tra single quotes
[ '
] non "si espandono", ma le variabili all'interno di double quotes
[ "
] lo faranno. Quindi, si deve cambiare tutto il single quotes
per double quotes
se contengono testo che si desidera sostituire con una variabile.
- Gli
sed
intervalli contengono anche una $
e sono immediatamente seguiti da una lettera come: $p
, $d
, $w
. Essi potranno anche guardare come le variabili di essere ampliato, in modo da avere per sfuggire quei $
personaggi con un backslash [ \
] come: \$p
, \$d
, \$w
.
grep 'TERMINATE' file