如何将字符串变量作为通配符参数传递给命令

如何将字符串变量作为通配符参数传递给命令

我有一个包含一些 tif 文件的目录,我想根据文件后缀将其合并在一起(注意文件名中的空格):

File1 P1.tif
File1 P2.tif
File1 P3.tif
File2 P1.tif
File2 P2.tif

应该会产生合并的 tif:

File1.tif
File2.tif

我有

for i in *\ P1.tif; do
    match=${i/\ P1/\ P*}
    out=${i/\ P1/}
    echo "processing $match"
    tiffcp "$match" "$out"
done

$match将包含File1 P*.tif并将$out包含File1.tif.但 tiffcp 会将第一个参数作为字符串处理,并且找不到匹配的文件。如果文件名中的空格不使用引号,$match将导致没有匹配的文件

所以问题是:如何将通配符字符串作为参数传递给命令?

答案1

如果您希望在参数扩展时执行通配符(顺便说一句,这是在调用命令之前由 shell 执行的;该命令看到的是结果文件,而不是模式),那么您就可以将参数扩展保留为不带引号的位置。

不加引号的参数扩展意味着分词和通配符(有时称为概念性 split+glob 运算符)。在这里,您只需要通配部分,因此您需要禁用拆分部分(通过为特殊$IFS变量分配空值):

IFS= # disable splitting
for i in ./*\ P1.tif; do
    match=${i/\ P1/\ P*}
    out=${i/\ P1/}
    echo "processing $match"
    tiffcp $match "$out" # split+glob on $match
done

假设文件名的前导部分不包含通配符。或者,你可以这样做:

for i in ./*\ P1.tif; do
    prefix=${i%\ P1.tif}
    out=$prefix.tif
    echo "processing $prefix"
    tiffcp "$prefix P"*.tif "$out"
done

这样,只有它*被视为 glob 运算符,并且该代码还具有仅使用标准 sh 语法的优点。

请注意,全局扩展按词法排序,因此 P10 将位于 P2 之前。使用zsh及其numericglobsort选项(或nglob 限定符)进行数字排序。

相关内容