第一次来这里,如果有什么遗漏的话,我深表歉意。
我目前正在编写一个脚本,用于搜索每个文件夹并查找一个<filename>.vmdk
文件,然后我想ls -lah
对此文件执行操作。
这是我当前的脚本代码。
#!/bin/bash
parse_dir () {
for file in ./**/*[A-Za-z][!-flat][!-thin].vmdk; do
#echo "File Found: "${file//\ /\\\ }
ls -lah "${file//\ /\\\ }"
#vmkfstools -i "${file//\ /\\\ }" -d thin "${file%.vmdk}-thin.vmdk"
#echo "New provisioned file: ${file%.vmdk}-thin.vmdk"
done
}
parse_dir
该脚本输出所有匹配的文件,如下所示:
ls: ./ABC\ Collector/ABC\ Collector.vmdk: No such file or directory
然而!如果我手动输入ls -lah ./ABC\ Collector/ABC\ Collector.vmdk
这个文件存在就好了。
我在这里错过了什么吗?
答案1
当空格是引用扩展的结果时,您不需要转义它们。
$ touch 'some file.txt'
$ ls -l some\ file.txt
-rw-r--r-- 1 ilkkachu ilkkachu 0 Sep 17 01:03 some file.txt
$ f='some file.txt'
$ ls -l "$f"
-rw-r--r-- 1 ilkkachu ilkkachu 0 Sep 17 01:03 some file.txt
事实上,正如您所看到的,它不起作用。引号和转义仅在变量扩展之前是特殊的,而扩展结果产生的引号则不然。在 shell 命令行中扩展变量与仅将变量内容按字面意思放在命令行中的同一位置不同。 (它不是宏处理器,而是编程语言。)
$ s='foo\ bar'
$ printf ':%s\n' $s
:foo\
:bar
$ printf ':%s\n' "$s"
:foo\ bar
如果不带引号, 的值s
会在空格上分割(按 的内容IFS
),而带引号则不会。在这两种情况下,反斜杠都不会逃逸空格。
在这样的 for 循环中,你可以这样做
for f in ./**/*.vmdk; do
ls -l "$f"
done
尽管请注意,这*[A-Za-z][!-flat][!-thin].vmdk
可能并不符合您的意思,[A-Za-z]
它匹配一个字母字符,并[!-flat]
匹配任何一不是-
、f
、l
、a
或 的字符t
。例如,这将包括abc.vmdk
,但不包括bac.vmdk
。
相反,使用另一个条件来排除不需要的情况:
for file in ./**/*.vmdk; do
case "$file" in
*-flat.vmdk) continue;;
*-thin.vmdk) continue;;
esac
echo "found: $file"
ls -l "$file"
new=${file%.vmdk}-thin.vmdk
# vmkfstools -i "$file" -d thin "$new"
# echo "New provisioned file: $new"
done
看:
答案2
文件名中的空格会讨厌你,你也会讨厌它们,特别是当将它们从文件名传递到通配符到脚本化 shell 命令时。让find
我们xargs
为您完成繁重的工作:
$ tree
.
+--- ABC Collector
| +--- ABC Collector-flat.vmdk
| +--- ABC Collector-thin.vmdk
| +--- ABC Collector.vmdk
$ find . -type f -name '*.vmdk' -not -name '*-flat.vmdk' -not -name '*-thin.vmdk' -print0 | xargs -0 ls -lah
-rw-r--r-- 1 myuser mygroup 0 Sep 16 14:29 ./ABC Collector/ABC Collector.vmdk