了解grep命令的bash脚本

了解grep命令的bash脚本,bash,grep,Bash,Grep,我早些时候发布了类似的东西。我正在尝试使用命令$。/user mburkhar检查用户是否联机,该命令打印出mburkhar已登录。我的程序工作正常,但如果我只是键入$。/user mb也是状态mb已登录。我所拥有的很好,但是有没有一种方法可以精确匹配用户键入的内容,而不是略微匹配前两个字符 这是我的程序,你可以看到我做了什么: # Check if a user is logged on if [ -z $1 ] ; then read user else user=$1 f

我早些时候发布了类似的东西。我正在尝试使用命令
$。/user mburkhar
检查用户是否联机,该命令打印出
mburkhar已登录
。我的程序工作正常,但如果我只是键入
$。/user mb
也是状态
mb已登录
。我所拥有的很好,但是有没有一种方法可以精确匹配用户键入的内容,而不是略微匹配前两个字符

这是我的程序,你可以看到我做了什么:

# Check if a user is logged on

if [ -z $1 ] ; then
    read user
else
    user=$1
fi

if [ `who | cut -d" " -f1 | grep $1` ] ; then
    echo "$1 is logged on"
else
    echo "$1 is either not valid or logged on"
fi

您可以使用grep的
-w
-word regexp
)选项仅匹配整个单词。将脚本中的
grep$1
替换为
grep-w$1
应该可以解决此问题。

指定字符串锚定的开头和结尾,如下所示:

if [ -z $1 ] ; then
    read user
else
    user="^$1$"
fi

if [ $(who | cut -d" " -f1 | grep $user | uniq ) ] ; then
    echo "$1 is logged on"
else
    echo "$1 is either not valid or logged on"
fi
我还添加了
uniq
,以删除重复的匹配项,以防用户获得多个tty,或者
[
将带着:
[:太多参数退出,以补充:

-w
运行良好,并得到广泛支持(GNU Grep、BSD Grep),但是

在您的情况下,如果您的输出行只包含一个用户名,而不包含任何其他内容,那么使用
-x
-匹配整个行也有意义(并且它符合POSIX)。
此外,由于您正在搜索文字用户名,因此最好使用
grep
-F
选项来指示该用户名

使用
[$(…)]
(或
[`…`]
)测试命令的非空输出有点脆弱和低效;更好、更简单的方法是:

  • 直接使用命令
  • 根据退出代码进行测试
  • 并在需要时抑制标准输出

    • grep
      -q
      选项不仅会抑制stdout,而且还会在找到第一个匹配项后终止搜索(退出代码
      0
      表示成功),从而提高搜索效率:

类似地,
[-z$1]
是脆弱的,因为如果传递了带有嵌入空格的参数,则该参数将中断—在本例中不太可能,但它是脆弱的(或者,如果必须保持POSIX兼容,
[-z“$1”]
)。
[…]]
之外,习惯性地双引号引用变量是有意义的,例如
grep
命令中的
$1

如果我们把这一切放在一起:

# Check if a user is logged on
if [[ -z $1 ]]; then
    read user
else
    user=$1
fi

if who | cut -d' ' -f1 | grep -Fxq "$1"; then
    echo "$1 is logged on"
else
    echo "$1 is either not valid or logged on"
fi
# Check if a user is logged on
if [[ -z $1 ]]; then
    read user
else
    user=$1
fi

if who | cut -d' ' -f1 | grep -Fxq "$1"; then
    echo "$1 is logged on"
else
    echo "$1 is either not valid or logged on"
fi