bash 理解 grep 命令的脚本
bash script with grep command understanding
我之前发布过类似的内容。我正在尝试使用打印出 mburkhar is logged on
的命令 $ ./user mburkhar
检查用户是否在线。我的程序运行正常,但如果我只键入 $ ./user mb
,也会显示 mb is logged on
。我拥有的很好,但是有没有办法完全匹配用户输入的内容,而不是稍微匹配前 2 个字符..?
这是我的程序,所以你可以看到我做了什么:
# Check if a user is logged on
if [ -z ] ; then
read user
else
user=
fi
if [ `who | cut -d" " -f1 | grep ` ] ; then
echo " is logged on"
else
echo " is either not valid or logged on"
fi
您可以使用 grep 的 -w
(--word-regexp
) 选项来只匹配整个单词。在脚本中将 grep
替换为 grep -w
应该可以解决问题。
像这样指定字符串锚点的开始和结束:
if [ -z ] ; then
read user
else
user="^$"
fi
if [ $(who | cut -d" " -f1 | grep $user | uniq ) ] ; then
echo " is logged on"
else
echo " is either not valid or logged on"
fi
我还添加了 uniq
以删除重复的匹配项,以防用户获得多个 tty,否则 [
将退出:[: too many arguments
补充:
-w
运行良好并得到广泛支持(GNU Grep、BSD Grep),但 it is not POSIX-compliant.
在你的情况下,假设你的输出行包含 just 一个用户名,没有别的,使用 -x
- 匹配 entire 行 - 也有意义(它 是 POSIX 兼容的)。
此外,由于您正在搜索 文字 用户名,因此最好使用 grep
的 -F
选项来指明这一点。
使用[ $(...) ]
(或[ `...` ]
)来测试命令的非空输出有点脆弱且效率低下;更好更简单的是:
- 直接使用命令
- 根据退出代码
进行测试
并在需要时抑制标准输出
grep
的 -q
选项不仅抑制标准输出,而且通过在 first 找到匹配项(退出代码 0
表示成功):
if who | cut -d' ' -f1 | grep -Fxq ""; then # ...
同样,[ -z ]
是脆弱的,因为如果传递带有嵌入空格的参数,它会中断 - 在 这种 情况下不太可能,但它是 (或者,如果您必须保持 POSIX 合规,[ -z "" ]
)。
在 [[ ... ]]
之外,习惯性地用双引号引用变量是有意义的,例如 grep
命令中的 </code>。</p>
<p>如果我们把它们放在一起:</p>
<pre><code># Check if a user is logged on
if [[ -z ]]; then
read user
else
user=
fi
if who | cut -d' ' -f1 | grep -Fxq ""; then
echo " is logged on"
else
echo " is either not valid or logged on"
fi
我之前发布过类似的内容。我正在尝试使用打印出 mburkhar is logged on
的命令 $ ./user mburkhar
检查用户是否在线。我的程序运行正常,但如果我只键入 $ ./user mb
,也会显示 mb is logged on
。我拥有的很好,但是有没有办法完全匹配用户输入的内容,而不是稍微匹配前 2 个字符..?
这是我的程序,所以你可以看到我做了什么:
# Check if a user is logged on
if [ -z ] ; then
read user
else
user=
fi
if [ `who | cut -d" " -f1 | grep ` ] ; then
echo " is logged on"
else
echo " is either not valid or logged on"
fi
您可以使用 grep 的 -w
(--word-regexp
) 选项来只匹配整个单词。在脚本中将 grep
替换为 grep -w
应该可以解决问题。
像这样指定字符串锚点的开始和结束:
if [ -z ] ; then
read user
else
user="^$"
fi
if [ $(who | cut -d" " -f1 | grep $user | uniq ) ] ; then
echo " is logged on"
else
echo " is either not valid or logged on"
fi
我还添加了 uniq
以删除重复的匹配项,以防用户获得多个 tty,否则 [
将退出:[: too many arguments
补充
-w
运行良好并得到广泛支持(GNU Grep、BSD Grep),但 it is not POSIX-compliant.
在你的情况下,假设你的输出行包含 just 一个用户名,没有别的,使用 -x
- 匹配 entire 行 - 也有意义(它 是 POSIX 兼容的)。
此外,由于您正在搜索 文字 用户名,因此最好使用 grep
的 -F
选项来指明这一点。
使用[ $(...) ]
(或[ `...` ]
)来测试命令的非空输出有点脆弱且效率低下;更好更简单的是:
- 直接使用命令
- 根据退出代码 进行测试
并在需要时抑制标准输出
grep
的-q
选项不仅抑制标准输出,而且通过在 first 找到匹配项(退出代码0
表示成功):if who | cut -d' ' -f1 | grep -Fxq ""; then # ...
同样,[ -z ]
是脆弱的,因为如果传递带有嵌入空格的参数,它会中断 - 在 这种 情况下不太可能,但它是 [ -z "" ]
)。
在 [[ ... ]]
之外,习惯性地用双引号引用变量是有意义的,例如 grep
命令中的 </code>。</p>
<p>如果我们把它们放在一起:</p>
<pre><code># Check if a user is logged on
if [[ -z ]]; then
read user
else
user=
fi
if who | cut -d' ' -f1 | grep -Fxq ""; then
echo " is logged on"
else
echo " is either not valid or logged on"
fi