Fré*_*ahé 10 shell bash wildcards
我的印象是./*.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}
Run Code Online (Sandbox Code Playgroud)
.
..
a.fastq
b.fastq
c.fastq
.fastq
# match all:
a.fastq
b.fastq
c.fastq
# with ./:
./a.fastq
./b.fastq
./c.fastq
Run Code Online (Sandbox Code Playgroud)
既不匹配*.fastq
也不./*.fastq
匹配文件.fastq
。所以我现在想知道,在这里使用./*.fastq
或./*
一般使用有什么意义吗?
Jef*_*ler 15
这最初是令人惊讶的通配符行为,因为*
通配符的描述说:
匹配任何字符串,包括空字符串。
... 直到您意识到当它是文件名的第一个字符时,句点有点特殊。中的介绍性文字是这样3.5.8 Filename Expansion
说的:
当模式用于文件名扩展时,字符 '.' 除非设置了 shell 选项 dotglob,否则在文件名的开头或紧跟在斜杠后面的必须显式匹配。
通配符前缀的“使用模式” ./
正如 steeldriver 评论的那样,在 bash shell 中处理带有前导破折号的名称时很有用。它对通配符/文件名扩展没有影响,但如果文件名以那些程序可能会误解为选项的字符开头,则可以更安全/更轻松地处理文件名。例如:
# I want a file named `-n`
$ touch -n
touch: invalid option -- 'n'
Try 'touch --help' for more information.
$ touch -- -n
### ok
$ touch ./-n
### ok
Run Code Online (Sandbox Code Playgroud)
......现在我 有一个名为 的文件-n
,如果我碰巧用通配符遍历它:
for file in *n
do
echo "$file"
done
Run Code Online (Sandbox Code Playgroud)
...我没有输出!
但是如果我在通配符前面加上 ./
,
for file in ./*n
do
echo "$file"
done
./-n
Run Code Online (Sandbox Code Playgroud)
...我看到文件名。
这是一个用于演示目的的简单示例;另请参阅为什么 printf 比 echo 好?出于这个原因和其他原因。其他实用程序会被其他选项绊倒,因此最好尽可能安全地将文件名提供给实用程序。如果您没有将通配符作为“转义”文件名的前缀,则必须以其他方式“保护”您的实用程序;一种常见的方法是用 表示选项的结束--
,例如:
for file in *n
do
mv -- "$file" backup/"$file"
done
Run Code Online (Sandbox Code Playgroud)
...这将安全地将-n
文件名传递给mv
(如下所示set -x
):
mv -- -n backup/-n
Run Code Online (Sandbox Code Playgroud)