Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Bourne Shell脚本测试对文件夹中的两个相同文件类型抛出错误?_String_Shell_Syntax_Sh - Fatal编程技术网

String Bourne Shell脚本测试对文件夹中的两个相同文件类型抛出错误?

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 正则表达式测试对于这里的工作来说几乎肯定是错误的工具,但

我正在编写一个Bourne脚本,希望选择与某些正则表达式匹配的文件。我用一个if测试结构来做这件事,它标识了一个以.o结尾的文件。但是,当我搜索的目录中有两个文件以.o结尾时,会出现以下错误:expr:syntax error。这怎么可能呢

    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是否值得。