I have a script that outputs about 10 lines every time if it run. The content of these lines varies.
I would really like to be able to grep
in the output and do different things depending on the output.
In pseudo this is what I would like to do
cat /etc/password | \\
if [ grep "root" $STDOUT ]; then
echo "root is found"
elif [ grep "nobody" $STDOUT ]; then
echo "nobody is found"
fi
Here have I used cat /etc/password
as an example, but it should be replaced with my scripts mentioned above.
The problem is, how do I get hold of the output from cat /etc/password
in the if
/elif
conditions?
The pipe takes output from one command and uses it as input for another. And, you're not limited to a single piped command—you can stack them as many times as you like, or until you run out of output or file descriptors.
The if statement is composed of the if keyword, the conditional phrase, and the then keyword. The fi keyword is used at the end of the statement. The COMMANDS gets executed if the CONDITION evaluates to True. Nothing happens if CONDITION returns False; the COMMANDS are ignored.
A pipe in Bash takes the standard output of one process and passes it as standard input into another process. Bash scripts support positional arguments that can be passed in at the command line.
You just do :
if grep -q "root" /etc/passwd ; then
...
fi
which will play the ...
commands if grep exit code is 0.
remember that \[
is a external command, probably located in /usr/bin/[
(normally it's a hard link to test
and when invoked as [
it requires a matching ]
argument). Also see the pitfalls page here, many of them deal are related to that command.
I'd suggest using awk:
cat /etc/passwd | awk '/root/{ do something }/nobody/{ do something else }'
You can achieve the same in bash using an expression like:
cat /etc/passwd |
while read; do
if echo "$REPLY" | fgrep root; then
something
fi
if echo "$REPLY" | fgrep nobody; then
something_else
fi
done
However the pure bash solution is less efficient for large inputs because it runs separate instances of grep
for every line.
As @Benoit recommends, just use grep
directly.
As @larsmans notes, you can avoid a double-read of the file by reading it into a variable once.
Given the availability of bash
I'd do it like this:
password=$(< /etc/passwd)
if grep -q root <<< "$password" ; then
echo root found
elif grep -q nobody <<< "$password" ; then
echo nobody found
fi
One read of the file, one or two invocations of grep
, no other processes or subshells launched.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With