Jak uzyskać status wyjścia przy użyciu polecenia sed?

11

grepKomenda daje się status wyjścia:

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

Ale muszę użyć sedi zdałem sobie sprawę, że nie ma statusu wyjścia:

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

Wiem, że powinienem grać z tą -qopcją, ale mi się nie udało.

Josef Klimuk
źródło
7
Pamiętaj, że z sedpewnością ma status wyjścia, po prostu nie robi tego, czego potrzebujesz tutaj. Jeśli sedpolecenie nie powiedzie się, na przykład, jeśli spróbujesz uruchomić go na pliku, do którego nie masz dostępu do zapisu lub plik, który nie istnieje, sedzakończy działanie ze statusem wyjścia innym niż 0. Status wyjścia wskazuje tylko, czy sedudało się zrobić to, co mu kazano, i echo "foo.bar" | sed 's/pop.*$//'został poprawnie wykonany. Usunął wszystkie linie za pomocą pop. To, że nie było takich linii, nie ma znaczenia, polecenie nadal działało.
terdon
@Zanna Zamierzałem opublikować odpowiedź, ale czułem, że to nie odpowiada na pytanie. Wyjaśnia tylko nieporozumienie, ale nie zapewnia pomocnego rozwiązania, jakie ma poniżej steeldriver. Tak więc komentarz wydawał się bardziej odpowiedni.
terdon

Odpowiedzi:

13

Możesz użyć q n, aby wyjść ze statusem wyjścia n - ale aby było to przydatne, będziesz musiał także użyć Rozgałęzienia i Kontroli Przepływu :

t
rozgałęzienie warunkowo (to znaczy: przeskocz do etykiety) tylko wtedy, gdy s/// polecenie zakończyło się powodzeniem od czasu odczytania ostatniego wiersza wejściowego lub podjęto inną rozgałęzienie warunkowe.

Prawdopodobnie najlepiej wybrać wartość n, która różni się od jednej ze standardowych wartości statusu wyjścia:

Status wyjścia równy zero oznacza sukces, a niezerowa wartość oznacza niepowodzenie. GNU „sed” zwraca następujące wartości błędów statusu wyjścia:

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.

Na przykład

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

natomiast

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

Jeśli chcesz pominąć domyślne drukowanie przestrzeni wzorów, zamień qna Q(zauważ, że Qjest to rozszerzenie GNU).

steeldriver
źródło
1

Oto jak szukać wyrażenia regularnego za pomocą sed i wyróżniać dopasowania lub zwrócić kod wyjścia (5), jeśli nie znaleziono dopasowania:

To jest input.txt:

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

Oto moja funkcja, aby wydrukować wszystko + Dopasuj wyróżnienia + Zwróć kod wyjścia:

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

$ highlight „lo \ | end” input.txt || echo -e "\ n * Nie znaleziono dopasowania *"

hel lo tam
moi drodzy starych fri kończy
się lo t rzeczy
będziemy przejść lo NG końca

Gdy nie ma dopasowania, zwróci kod wyjścia (5). Możesz go używać z kotem i fajką | także:

$ cat input.txt | wyróżnij „hot \ | i” || echo -e "\ n * Nie znaleziono dopasowania *"

cześć
mój drogi stary przyjacielu,
wiele rzeczy
przekażemy na końcu

* Nie znaleziono dopasowania *

Dzięki https://unix.stackexchange.com/a/405725/43233 - Używam go + opcja wyjścia z sed.

Noam Manos
źródło