Reputation: 25986
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?
Upvotes: 20
Views: 43101
Reputation: 1919
I have a simple example for pipe
to statement without if
keyword :
echo -e hello | [ $(cat) == hello ] && echo "Ok"
with else
too easy :
echo -e hello | ([ $(cat) == 'bye' ] && echo "Ok" || echo "No Okey")
For example you want to check status code of http response is equal to 200 or not :
curl http://google.com -w "%{http_code}" -s -o /dev/null | [ $(cat) == 200 ] && echo "Request successful processed"
# Note: in this example google response is 403 .
Upvotes: 2
Reputation: 11
How about the following:
#!/bin/bash
if [ -z $1 ]; then
echo Usage: $0 [UID to search for]
exit 1;
fi
SEARCHID="$1"
function notFound() {
echo NOT FOUND
}
function found() {
echo Found it
}
function main() {
grep -i $SEARCHID /etc/passwd
# Move $? to a variable
SEARCHRESULT=$?
if [ "$SEARCHRESULT" != "0" ]; then
notFound;
else
found;
fi
}
# call main function
main
Upvotes: 1
Reputation: 163
Just use &&:
grep -q root /etc/password && echo "root is found"
grep -q nobody /etc/password && echo "nobody is found"
Upvotes: 1
Reputation: 189367
In the general case, you could use a temporary file.
t=$(mktemp -t passwd.XXXXXXXX)
trap 'rm $t' 0
trap 'exit 127' 1 2 3 5 15
cat >$t
for u in root nobody; do
fgrep $u $t
done
The trap
s are to remove the temporary file afterwards.
As an aside, you can pipe to an if
, but the first grep
inside your conditional would already consume all of its standard input. It's more useful in situations like this:
if $option_count ; then
wc -l
else
tac
fi <file
Upvotes: 0
Reputation: 26086
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.
Upvotes: 9
Reputation: 10020
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.
Upvotes: 5
Reputation: 79175
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.
Upvotes: 4
Reputation: 363547
Piping into an if-statement is possible with subshells, but that solution will break since you're running two grep
commands on the pipe, the first of which will exhaust it.
The best solution in your case is probably to read /etc/passwd
into a variable, then grep
it:
passwd=$(cat /etc/passwd)
if (echo $passwd | grep -q root); then
echo "root found"
fi
if (echo $passwd | grep -q nobody); then
echo "nobody found"
fi
Upvotes: 3