我有一个脚本,如果它运行,每次输出大约10行。这些行的内容各不相同。
我真的希望能够 grep
在输出中,根据输出做不同的事情。
在伪这是我想做的
cat /etc/password | \\
if [ grep "root" $STDOUT ]; then
echo "root is found"
elif [ grep "nobody" $STDOUT ]; then
echo "nobody is found"
fi
我用过这里 cat /etc/password
作为一个例子,但它应该用我上面提到的脚本替换。
问题是,我如何获得输出 cat /etc/password
在里面 if
/elif
条件?
正如@Benoit建议的那样,只需使用 grep
直。
正如@larsmans所说,你可以通过将文件读入变量一次来避免双重读取文件。
鉴于可用性 bash
我这样做:
password=$(< /etc/passwd)
if grep -q root <<< "$password" ; then
echo root found
elif grep -q nobody <<< "$password" ; then
echo nobody found
fi
一次读取文件,一次或两次调用 grep
,没有推出其他流程或子壳。
你这样做:
if grep -q "root" /etc/passwd ; then
...
fi
哪个会起作用 ...
命令如果grep退出代码为0。
记得那个 \[
是一个外部命令,可能位于 /usr/bin/[
(通常这是一个很难的链接 test
当被调用为 [
它需要匹配 ]
论据)。另见 陷阱 这里的页面,其中许多交易都与该命令有关。
我建议使用awk:
cat /etc/passwd | awk '/root/{ do something }/nobody/{ do something else }'
您可以使用如下表达式在bash中实现相同的目的:
cat /etc/passwd |
while read; do
if echo "$REPLY" | fgrep root; then
something
fi
if echo "$REPLY" | fgrep nobody; then
something_else
fi
done
但是纯粹的bash解决方案对大型输入的效率较低,因为它运行的是单独的实例 grep
每一行。
使用子shell可以使用if语句,但是当你运行两个时,该解决方案将会中断 grep
管道上的命令,第一个将耗尽它。
您的案例中最好的解决方案可能是阅读 /etc/passwd
变成一个变量,然后 grep
它:
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
只需使用&&:
grep -q root /etc/password && echo "root is found"
grep -q nobody /etc/password && echo "nobody is found"
在一般情况下,您可以使用临时文件。
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
该 trap
s是之后删除临时文件。
除此之外,你 能够 管道到 if
,但第一个 grep
在条件内部已经消耗了所有标准输入。它在这样的情况下更有用:
if $option_count ; then
wc -l
else
tac
fi <file
以下怎么样:
#!/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