Grep 查找行首或中间的模式

Grep 查找行首或中间的模式

首先我要说的是,我认为这个问题并不像听起来那么无辜。

我需要做什么:检查 PATH 环境变量中的文件夹。它可能是在开始时或之后的某个地方。我只需要验证该文件夹是否存在。

我的问题的示例 - 让我们使用/opt/gnome.


场景 1:文件夹不在 PATH 的开头

# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome

# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome

请注意,grep 需要足够具体,以免捕获/var/opt/gnome.因此冒号。


场景 2:文件夹位于 PATH 的开头。

# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome

# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome

这是我的问题 - 我需要搜索此文件夹的冒号或行首。我想做的是这两个括号表达式之一:

# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"

[^[:有自己的含义。因此,上面的两个命令不起作用。

有没有一种方法可以在一个命令中 grep 这两种情况?

答案1

如果您正在检查环境变量的内容PATH,而不是在文件中查找某些内容,那么这grep是错误的工具。在 shell 中执行此操作更容易(更快,并且可以说更具可读性)。

在 bash、ksh 和 zsh 中:

if [[ :$PATH: = *:/opt/gnome:* ]]; then
 : # already there
else
  PATH=$PATH:/opt/gnome
fi

便携:

case :$PATH: in
  *:/opt/gnome:*) :;; # already there
  *) PATH=$PATH:/opt/gnome;;
esac

注意使用:$PATH:而不是$PATH;这样,该组件在搜索字符串中始终被冒号包围,即使它位于 的开头或结尾$PATH

如果您正在搜索文件的一行,那么您可以使用扩展的正则表达式(即需要grep -E(^|:)/opt/gnome($|:)来匹配/opt/gnome,但前提是它位于行的开头或冒号之后,并且仅当它位于行的末尾时该行或后跟一个冒号。

答案2

您可以通过使用扩展正则表达式grep -E

如果您想避免误报,则必须匹配要查找的路径的开头和结尾。

匹配开头的实例:

$ TEST=/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome

也匹配中间的实例:

$ TEST=/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome

避免误报:

$ TEST="/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta"
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"

那里没有匹配项。

紧凑而优雅。在 Debian 7 上测试。

答案3

如果您没有结婚grep,您可以使用awk并分离上的记录:

awk 'BEGIN {RS=":"} /^\/opt\/gnome$/'

答案4

我不知道这是否足以回答但是

grep -w "/opt/gnome"

会满足您的需求。

echo '/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome' | grep -w "/opt/gnome" -o
/opt/gnome
echo '/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome' | grep -w "/opt/gnome" -o
/opt/gnome

echo '/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome' | grep "/opt/gnome" -o
/opt/gnome
/opt/gnome

相关内容