Jam*_*esL 9 path shell-script text-processing
我首先要说的是,我认为这个问题没有听起来那么天真。
我需要做的是:检查 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
Run Code Online (Sandbox Code Playgroud)
请注意,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
Run Code Online (Sandbox Code Playgroud)
这是我的问题 - 我需要在此文件夹中搜索冒号或行首。我想做的是这两个括号表达式之一:
# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"
Run Code Online (Sandbox Code Playgroud)
BUT[^
和[:
有自己的含义。因此,上面的两个命令不起作用。
有没有一种方法可以在一个命令中对这两种情况进行 grep?
Gil*_*il' 10
如果您正在检查PATH
环境变量的内容,而不是在文件中查找某些内容,那么grep
就是错误的工具。在 shell 中执行它更容易(并且更快,可以说更具可读性)。
在 bash、ksh 和 zsh 中:
if [[ :$PATH: = *:/opt/gnome:* ]]; then
: # already there
else
PATH=$PATH:/opt/gnome
fi
Run Code Online (Sandbox Code Playgroud)
便携:
case :$PATH: in
*:/opt/gnome:*) :;; # already there
*) PATH=$PATH:/opt/gnome;;
esac
Run Code Online (Sandbox Code Playgroud)
注意使用:$PATH:
而不是$PATH
; 这样,即使组件位于$PATH
.
如果您正在搜索文件的一行,那么您可以使用扩展的正则表达式(即 required grep -E
)(^|:)/opt/gnome($|:)
进行匹配,/opt/gnome
但前提是它位于行首或冒号之后,并且仅当它位于行尾时行或后跟一个冒号。
您可以通过使用扩展正则表达式 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
Run Code Online (Sandbox Code Playgroud)
还匹配中间的实例:
$ TEST=/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
Run Code Online (Sandbox Code Playgroud)
避免误报:
$ TEST="/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta"
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
Run Code Online (Sandbox Code Playgroud)
那里没有比赛。
紧凑而优雅。在 Debian 7 上测试。
如果你没有结婚grep
,你可以使用awk
和分开记录:
awk 'BEGIN {RS=":"} /^\/opt\/gnome$/'
Run Code Online (Sandbox Code Playgroud)
你也可以使用
echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"
它将路径变量拆分为单独的行(每个路径一个),因此grep -x
可以查找确切的结果。这当然有一个缺点,它需要一个额外的过程tr
。当文件夹名称PATH
包含换行符时,它将不起作用。