bash脚本与grep命令的理解

时间:2015-04-07 01:17:33

标签: bash grep

我之前发布过类似的内容。我正在尝试使用命令$ ./user mburkhar检查用户是否在线,该命令打印出mburkhar is logged on。我的程序工作正常,但如果我只输入$ ./user mb,则状态为mb is logged on。我有什么不错,但有没有办法匹配用户输入的内容而不是略微匹配前2个字符..?

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

# 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

3 个答案:

答案 0 :(得分:1)

补充accepted answer

-w效果很好,受到广泛支持(GNU Grep,BSD Grep),但it is not POSIX-compliant

在您的情况下,假设您的输出行包含只是一个用户名,而不是其他任何内容,使用-x - 来匹配整个行 - 会有意义也是( POSIX兼容) 此外,由于您正在搜索文字用户名,因此使用grep -F选项来表示该用户名是一种很好的做法

使用[ $(...) ](或[ `...` ])来测试命令的非空输出有点脆弱且效率低下;它更好,更简单:

  • 直接使用命令
  • 将测试基于退出代码
  • 并根据需要抑制标准输出

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

      if who | cut -d' ' -f1 | grep -Fxq "$1"; then # ...
      

同样地,[ -z $1 ]是脆弱的,如果传递带有嵌入空格的参数会破坏 - 在这个的情况下不太可能,但它better to get in the habit of using [[ -z $1 ]](或者,如果您必须保持POSIX兼容,[ -z "$1" ]) 在[[ ... ]]之外,习惯性地引用变量引用是有意义的,例如$1命令中的grep

如果我们把它们放在一起:

# 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

答案 1 :(得分:0)

您可以使用grep的-w--word-regexp)选项仅匹配整个单词。在脚本中用grep $1替换grep -w $1应修复它。

答案 2 :(得分:0)

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

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,或[将退出:[: too many arguments