How do I get the exit status when using the sed command?
The grep
command gives out an exit status:
$echo "foo.bar" | grep -o foo
foo
$echo $?
0
$echo "foo.bar" | grep -o pop
$echo $?
1
But I need to use sed
and I realized that it has no exit status:
$echo "foo.bar" | sed 's/bar.*$//'
foo.
$echo $?
0
$echo "foo.bar" | sed 's/pop.*$//'
foo.bar
$echo $?
0
I know that I should play around with the -q
option, but I have not succeeded.
Solution 1:
You can use qn to quit with exit status n - but to make that useful, you will also need to use some Branching and Flow Control:
t
branch conditionally (that is: jump to a label) only if as///
command has succeeded since the last input line was read or another conditional branch was taken.
It is probably best to choose a value for n that is distinct from one of the standard exit status values:
An exit status of zero indicates success, and a nonzero value indicates failure. GNU 'sed' returns the following exit status error values:
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.
So for example
$ echo "foo.bar" | sed 's/bar.*$//; t; q42' ; echo $?
foo.
0
whereas
$ echo "foo.bar" | sed 's/baz.*$//; t; q42' ; echo $?
foo.bar
42
If you want to omit the default printing of the pattern space, then replace q
by Q
(note that Q
is a GNU extension).
Solution 2:
Here's how to search regex with sed, and highlight matches, or return exit code (5) if no match found:
This is input.txt:
hello there
my dear old friend
a lot of things
we'll pass along the end
Here's my function to Print all + Highlight matches + Return exit code:
highlight()
{
pattern=$1
shift
sed '/'"${pattern}"'/,${s//\x1b[32m&\x1b[0m/g;b};$q5' "$@"
}
$ highlight "lo\|end" input.txt || echo -e "\n* No match found *"
hello there
my dear old friend
a lot of things
we'll pass along the end
When there's no match, it will return exit code (5). You can use it with cat and pipe | as well:
$ cat input.txt | highlight "hot\|and" || echo -e "\n* No match found *"
hello there
my dear old friend
a lot of things
we'll pass along the end
* No match found *
Thanks to https://unix.stackexchange.com/a/405725/43233 - I'm using it + sed quit option.