我的印象是,./*.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