使用 glob 在 for 循环中指定 './' 有什么好处吗?

使用 glob 在 for 循环中指定 './' 有什么好处吗?

我的印象是,./*.fastq在搜索以.fastq.例如,./将阻止捕获文件.fastq。这显然是错误的,如下例所示:

TMP_DIR=$(mktemp --directory)
mkdir -p ${TMP_DIR}
(cd ${TMP_DIR}
 touch {a,b,c,}.fastq
 ls -a
 echo ""

 echo "# match all:"
 for f in *.fastq ; do
     echo "${f}"
 done
 echo ""

 echo "# with ./:"
 for f in ./*.fastq ; do
     echo "${f}"
 done
)
rm -rf ${TMP_DIR}
.
..
a.fastq
b.fastq
c.fastq
.fastq

# match all:
a.fastq
b.fastq
c.fastq

# with ./:
./a.fastq
./b.fastq
./c.fastq

既不匹配*.fastq也不./*.fastq匹配该文件.fastq。所以我现在想知道,./*.fastq这里使用或者./*一般来说有什么意义吗?

答案1

*这最初是令人惊讶的通配符行为,因为通配符的描述如下:

匹配任何字符串,包括空字符串。

...直到你意识到那个时期有点特殊第一的文件名的字符。中的介绍性文字3.5.8 Filename Expansion是这样说的:

当模式用于文件名扩展时,字符“.”文件名开头或紧跟在斜杠后面的字符必须显式匹配,除非设置了 shell 选项 dotglob。

通配符前缀的“使用模式”./对于在 bash shell 中处理以破折号开头的名称,正如 Steeldriver 评论的那样。它对通配符/文件名扩展没有影响,但是当您引用文件名时,如果它们以那些程序可能会误解为选项的字符开头,则可以更安全/更轻松地处理文件名。例如:

# I want a file named `-n`
$ touch -n
touch: invalid option -- 'n'
Try 'touch --help' for more information.
$ touch -- -n
### ok
$ touch ./-n
### ok

...现在我一个名为 的文件-n,如果我碰巧用通配符循环它:

for file in *n
do
  echo "$file"
done

...我没有得到任何输出!

但如果我在通配符前面加上./,

for file in ./*n
do
  echo "$file"
done
./-n

...我看到文件名。

这是一个用于演示目的的简单示例;也可以看看为什么 printf 比 echo 更好?由于这个原因和其他原因。其他实用程序会被其他选项绊倒,因此最好尽可能安全地向实用程序提供文件名。如果你将通配符作为“转义”文件名的前缀,您必须以其他方式“保护”您的实用程序;一常见的一种是用 表示选项结束--,例如:

for file in *n
do
  mv -- "$file" backup/"$file"
done

...它将安全地将-n文件名传递给mv(如下所示set -x):

mv -- -n backup/-n

相关内容