String Bourne Shell脚本测试对文件夹中的两个相同文件类型抛出错误?
我正在编写一个Bourne脚本,希望选择与某些正则表达式匹配的文件。我用一个if测试结构来做这件事,它标识了一个以.o结尾的文件。但是,当我搜索的目录中有两个文件以.o结尾时,会出现以下错误:expr:syntax error。这怎么可能呢String Bourne Shell脚本测试对文件夹中的两个相同文件类型抛出错误?,string,shell,syntax,sh,String,Shell,Syntax,Sh,我正在编写一个Bourne脚本,希望选择与某些正则表达式匹配的文件。我用一个if测试结构来做这件事,它标识了一个以.o结尾的文件。但是,当我搜索的目录中有两个文件以.o结尾时,会出现以下错误:expr:syntax error。这怎么可能呢 if test "`expr \"$file\" : ${SPECIFIED_DIRECTORY}/*.o`" != "0"; then do something fi 正则表达式测试对于这里的工作来说几乎肯定是错误的工具,但
if test "`expr \"$file\" : ${SPECIFIED_DIRECTORY}/*.o`" != "0"; then
do something
fi
正则表达式测试对于这里的工作来说几乎肯定是错误的工具,但是让我们假设,为避免与环境变量和内置项发生冲突,按照约定指定的_目录小写,它包含一个正则表达式来匹配目录名,而不是文字名,因此实际上是正确的工具。如果是这样的话,你会想写
if expr "$file" : "$specified_directory"/'.*[.]o' >/dev/null; then
...
fi
没有测试命令,没有子shell。保持简单
如果你不逃过这一关。在本例中,通过将其设置为字符类[.],它具有正常的正则表达式含义,即只匹配一个字符。类似地,.*是匹配正则表达式中零个或多个字符的方法,而不是裸*这是fnmatch语法。如果我理解正确,如果目录中有.o文件,请执行以下操作:
if find "$dir"/*.o >/dev/null 2>&1; then
# do something
fi
仅当存在任何匹配文件时,“查找”命令才会成功退出。否则它将失败退出,then块将不会执行。>/dev/null 2>&1用于隐藏stdout和stderr。这种方法适用于任何POSIX shell,并且不调用shell内置的不可用工具,因此在运行时非常有效
contains_any_files() {
set -- "$1"/*
[ "$#" -gt 0 ] && [ -f "$1" ]
}
if contains_any_files "$dir"; then
...
fi
想想看。*.o正则表达式在expr运行之前进行了扩展,因此它在右侧通过了不止一个参数。顺便说一下,在现代系统上/bin/sh是POSIX sh,它实际上更接近ksh88,而不是Bourne,它实际上是70年代的外壳。你确定你的目标是伯恩吗?谢谢查尔斯!我缺乏经验,容易做出错误的决定和产生误解。非常感谢您为我指明了正确的方向。&>不是POSIX。该问题明确要求使用/bin/sh.@CharlesDuffy I将ls替换为find。现在它更有意义了。我不知道是什么驱使我首先使用ls…好吧,按照你在那里写的方式,shell在find开始之前就开始扩展glob,如果已经扩展了名称,就传递find一个列表,如果它们存在,或者如果没有,就传递一个不存在的glob。这是可行的,但我不确定使用find是否值得。