我正在尝试这个问题中提出的答案:Test whether a glob has any matches in bash
if test -n "$(find . -maxdepth 1 -name 'glob*' -print -quit)"
then
echo found
else
echo not found
fi
但是,我在带变量的脚本中这样做。
#!/bin/sh
directory=~/nd
glob="*12*.idx"
cd $directory
if test -n "$(find . -maxdepth 1 -name \"$glob\" -print -quit)"
then
echo found
else
echo not found
fi
运行脚本会给我:
not found
但是自己运行命令
find . -maxdepth 1 -name "*12*.idx" -print -quit
给我一个结果
./notes_archive_2012.idx
这是引用问题吗?
答案 0 :(得分:1)
是的,这是一个引用问题。报价不应在$(...)
内转义。考虑:
test -n "$(find . -maxdepth 1 -name \"$glob\" -print -quit)" # Wrong
在上面的表格中,-name
看到的find
的参数以文字双引号开头和结尾。如果文件名本身以双引号开头和结尾,它只匹配文件名。
以下是您想要的:
test -n "$(find . -maxdepth 1 -name "$glob" -print -quit)" # Right
来自man bash
:
使用$(命令)表单时,括号之间的所有字符 使 命令;没有人受到特别对待。
换句话说,如果你想在$(...)
内的命令中使用双引号,只需使用双引号。 $(...)
中的命令应该像在命令行中单独输入一样编写。
答案 1 :(得分:0)
您可以在没有外部命令的情况下执行此操作。一种方法是滥用for
循环:
# Use the loop as a context for expanding the glob, not actually iterating
# over the results.
for f in $glob; do
if [[ -f "$f" ]]; then
echo found
else
echo not found
fi
break
done
您也可以使用数组:
files=( $glob )
if [[ -f "${files[0]}" ]]; then
echo found
else
echo not found
fi
答案 2 :(得分:0)
查找适用于本地文件但不适用于远程文件的文件或任何其他文件本地不存在的文件。有时您想要检查任意匹配,并且模式是字符串。
bash支持[[ "$string" == shellmatch* ]]
和[[ "$string" =~ ^regexmatch.* ]]
但不支持任何形式的[[ "$string" == "$shellmatch" ]]
,其中match参数是字符串。我还没有找到任何方法来欺骗bash处理字符串,而不是写出正确格式化的新shell脚本,并且我不相信空格或]]括号将得到正确支持。
在Rich’s sh (POSIX shell) tricks是一个单行程,可以使用大多数POSIX shell,只使用大小写和一些聪明的引用。测试使用bash,sh。测试不适用于zsh。
fnmatch () { case "$2" in $1) return 0 ;; *) return 1 ;; esac ; }
我使用这个变体,所以我可以得到空白以匹配所有
fnmatch () { [ -z "$1" ] && return 0; case "$2" in $1) return 0 ;; esac; return 1 ; }
fnmatch 'ab \?def' 'ab ?def' && echo 'matched' # \ supported
fnmatch 'ab ?def' 'ab cdef' && echo 'matched' # ? supported
fnmatch 'ab [cd]def' 'ab cdef' && echo 'matched' # [] supported
fnmatch 'ab {c,d}def' 'ab cdef' && echo 'matched' # case does not support brace expansion
fnmatch 'ab c*' 'ab cdef' && echo 'matched' # space supported
fnmatch 'ab) c*' 'ab) cdef' && echo 'matched' # ) supported, does not interfere with case