Come posso ottenere lo stato di uscita quando uso il comando sed?


11

Il grepcomando fornisce uno stato di uscita:

$echo "foo.bar" | grep -o foo
foo
$echo $?
0
$echo "foo.bar" | grep -o pop
$echo $?
1  

Ma devo usare sede mi sono reso conto che non ha uno stato di uscita:

$echo "foo.bar" | sed 's/bar.*$//'
foo.
$echo $?
0
$echo "foo.bar" | sed 's/pop.*$//'
foo.bar
$echo $?
0  

So che dovrei giocare con l' -qopzione, ma non ci sono riuscito.


7
Nota che sedsicuramente ha uno stato di uscita, semplicemente non fa quello che ti serve qui. Se il sedcomando non riesce, ad esempio, se si tenta di eseguirlo su un file per il quale non si ha accesso in scrittura o su uno inesistente, si seduscirà con uno stato di uscita diverso da 0. Lo stato di uscita indica semplicemente se sedsei riuscito a fare ciò che gli hai detto di fare ed è echo "foo.bar" | sed 's/pop.*$//'stato eseguito correttamente. Ha eliminato tutte le righe con pop. Che non esistessero tali righe è irrilevante, il comando ha ancora funzionato.
terdon,

@Zanna Avevo intenzione di pubblicare una risposta, ma ho sentito che in realtà non risponde alla domanda. Spiega solo un malinteso, ma non fornisce una soluzione utile come Steeldriver ha di seguito. Quindi un commento sembrava più appropriato.
terdon,

Risposte:


13

Puoi usare q n per uscire con lo stato di uscita n - ma per renderlo utile, dovrai anche usare alcuni Branching e Flow Control :

t
ramo in modo condizionale (ovvero: passa a un'etichetta) solo se un s/// comando ha avuto esito positivo dall'ultima lettura della riga di input o da un altro ramo condizionale.

Probabilmente è meglio scegliere un valore per n che sia distinto da uno dei valori standard dello stato di uscita:

Uno stato di uscita pari a zero indica un esito positivo e un valore diverso da zero indica un errore. GNU 'sed' restituisce i seguenti valori di errore dello stato di uscita:

0
 Successful completion.

1
 Invalid command, invalid syntax, invalid regular expression or a
 GNU 'sed' extension command used with '--posix'.

2
 One or more of the input file specified on the command line could
 not be opened (e.g.  if a file is not found, or read permission is
 denied).  Processing continued with other files.

4
 An I/O error, or a serious processing error during runtime, GNU
 'sed' aborted immediately.

Quindi per esempio

$ echo "foo.bar" | sed 's/bar.*$//; t; q42' ; echo $? 
foo.
0

mentre

$ echo "foo.bar" | sed 's/baz.*$//; t; q42' ; echo $? 
foo.bar
42

Se si desidera omettere la stampa predefinita dello spazio modello, sostituire qcon Q(si noti che Qè un'estensione GNU).


1

Ecco come cercare regex con sed, evidenziare le corrispondenze o restituire il codice di uscita (5) se non viene trovata alcuna corrispondenza:

Questo è input.txt:

hello there
my dear old friend
a lot of things
we'll pass along the end

Ecco la mia funzione per stampare tutto + Evidenzia corrispondenze + Codice uscita di ritorno:

highlight()
{
  pattern=$1
  shift
  sed '/'"${pattern}"'/,${s//\x1b[32m&\x1b[0m/g;b};$q5' "$@"
}

$ highlight "lo \ | end" input.txt || echo -e "\ n * Nessuna corrispondenza trovata *"

hel lo si
miei cari vecchi fri terminare
un lo t di cose
passeremo un lo ng alla fine

Quando non c'è corrispondenza, restituirà il codice di uscita (5). Puoi usarlo con cat and pipe | anche:

$ cat input.txt | evidenziare "hot \ | e" || echo -e "\ n * Nessuna corrispondenza trovata *"

ciao,
mio caro vecchio amico , passeremo
un sacco di cose
alla fine

* Nessuna corrispondenza trovata *

Grazie a https://unix.stackexchange.com/a/405725/43233 - Lo sto usando + opzione sed quit.

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.