当输入命令时,转义空格不能与“ls”一起使用

当输入命令时,转义空格不能与“ls”一起使用

第一次来这里,如果有什么遗漏的话,我深表歉意。

我目前正在编写一个脚本,用于搜索每个文件夹并查找一个<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]匹配任何不是-fla或 的字符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

相关内容