Jen*_*nny 14 command-line bash scripts
我编写了一个小的 bash 脚本来查找名为anaconda或miniconda在我的用户中的目录$HOME。但是它miniconda2在我家中找不到该目录。
我怎么能解决这个问题?
if [ -d "$HOME"/"(ana|mini)conda[0-9]?" ]; then
echo "miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
Run Code Online (Sandbox Code Playgroud)
PS:如果我有[ -d "$HOME"/miniconda2 ]; then,那么它会找到 miniconda2 目录,所以我认为错误在于部分"(ana|mini)conda[0-9]?"
我希望脚本是通用的。对我来说,它是 miniconda2,但对于其他一些用户,它可能是 anaconda2、miniconda3 等等。
ste*_*ver 13
这是一件非常棘手的事情,要做得很好。
从根本上说,-d只会测试单个参数 - 即使您可以使用正则表达式匹配文件名。
一种方法是翻转问题,并测试目录的正则表达式匹配,而不是测试目录的正则表达式匹配。换句话说,使用一个简单的 shell glob遍历所有目录$HOME,并针对您的正则表达式测试每个目录,打破匹配,最后测试BASH_REMATCH数组是否为非空:
#!/bin/bash
for d in "$HOME"/*/; do
if [[ $d =~ (ana|mini)conda[0-9]? ]]; then
break;
fi
done
if ((${#BASH_REMATCH[@]} > 0)); then
echo "anaconda/miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用扩展的 shell glob 代替正则表达式,并捕获数组中的任何 glob 匹配项。然后测试数组是否为非空:
#!/bin/bash
shopt -s extglob nullglob
dirs=( "$HOME"/@(ana|mini)conda?([0-9])/ )
if (( ${#dirs[@]} > 0 )); then
echo "anaconda/miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
Run Code Online (Sandbox Code Playgroud)
尾随/确保仅匹配目录;该nullglob防止了壳从在零个一致的情况下返回的不匹配的字符串。
要进行递归,请分别设置globstarshell 选项 ( shopt -s globstar),然后分别:-
(正则表达式版本): for d in "$HOME"/**/; do
(扩展全局版本): dirs=( "$HOME"/**/@(ana|mini)conda?([0-9])/ )
事实上,正如已经提到的,这很棘手。我的方法如下:
find及其正则表达式功能来查找有问题的目录。find打印一个xxes存储在字符串中因此:
xString=$(find $HOME -maxdepth 1 \
-type d \
-regextype egrep \
-regex "$HOME/(ana|mini)conda[0-9]?" \
-printf 'x');
if [ -n "$xString" ]; then
echo "found one of the directories";
else
echo "no match.";
fi
Run Code Online (Sandbox Code Playgroud)
解释:
find $HOME -maxdepth 1查找下面的所有内容,$HOME
但将搜索限制在一个级别(即:它不会递归到子目录中)。-type d将搜索限制为仅d搜索-regextype egrep告诉我们处理find什么类型的正则表达式。这是必需的,因为像[0-9]?和 之(…|…)类的东西有些特殊,find
并且默认情况下无法识别它们。-regex "$HOME/(ana|mini)conda[0-9]?"是我们要查找的实际
正则表达式-printf 'x'只x为
满足先前条件的每个事物打印一个。