【问题标题】:Why does echo command interpret variable for base directory?为什么 echo 命令解释基目录的变量?
【发布时间】:2020-10-03 21:42:12
【问题描述】:

我想在图片文件夹中找到一些文件类型,我在/home/user/pictures 文件夹中创建了以下 bash 脚本:

for i in *.pdf *.sh *.txt;
do
  echo 'all file types with extension' $i;
  find /home/user/pictures -type f -iname $i; 
done

但是,当我执行 bash 脚本时,对于位于 基本目录 /home/user/pictures 上的文件,它无法按预期工作。该命令不是 echo 'All File types with Extension *.sh',而是解释基目录的变量:

all file types with extension file1.sh
/home/user/pictures/file1.sh
all file types with extension file2.sh
/home/user/pictures/file2.sh
all file types with extension file3.sh
/home/user/pictures/file3.sh

我想知道为什么 echo - 命令不打印“所有扩展名为 *.sh 的文件类型”。

【问题讨论】:

  • 因为 $i 更改了文件名而不是扩展名,所以您使用了 glob (*) 字符,shell 会查找所有 .sh 文件。
  • *.pdf在循环开始迭代之前被扩展为一个PDF文件列表; i 未设置为字符串 *.pdf

标签: linux bash shell echo


【解决方案1】:

修改代码:

for i in '*.pdf' '*.sh' '*.txt'
do
    echo "all file types with extension $i"
    find /home/user/pictures -type f -iname "$i"
done

解释:

在 bash 中,包含 * 的字符串或扩展为此类字符串的变量可以扩展为 glob 模式,除非该字符串通过将其放在引号内来防止 glob 扩展(尽管如果 glob 模式确实不匹配任何文件,则在尝试扩展后将保留原始 glob 模式)。

在这种情况下,不希望发生全局扩展 - 包含 * 的字符串需要作为文字传递给每个 echofind 命令。所以$i 应该用双引号括起来——这将允许从$i 进行变量扩展,但不会发生随后的通配符扩展。 (如果改为使用单引号,即 '$i',则文字 $i 将被传递给 echofind,这也是不需要的。)

除此之外,如果当前目录中存在与任何 glob 模式匹配的任何文件,则初始 for 行需要使用引号来防止通配符扩展。在这里,使用单引号还是双引号都没有关系。

另外,这里修改后的代码也去掉了一些不必要的分号。 bash 中的分号是命令分隔符,不仅仅用于终止语句(如在 C 等中)。

使用原始代码观察到的行为

这里似乎发生的情况是,初始 for 语句中使用的模式之一是匹配当前目录中的文件(特别是 *.sh 匹配 file1.sh file2.shfile3.sh) .因此,它被表达式中的这些文件名 (file1.sh file2.sh file3.sh) 的列表替换,for 语句将遍历这些值。 (请注意,当前目录可能与脚本所在的目录或用于find 的顶级目录不同。)

仍然可以预期*.pdf*.txt 将在表达式中使用——是否被替换,取决于是否找到任何匹配项。因此问题中显示的输出可能不是脚本的整个输出。

【讨论】:

  • 非常感谢您的详细解释。我已经通过了您的修订,现在脚本按预期工作。 ☺️
【解决方案2】:

此类表达式 (*.blabla) 会更改循环中 $i 的值。这是我会做的技巧:

for i in pdf sh txt;
do
  echo 'all file types with extension *.'$i;
  find /home/user/pictures -type f -iname '*.'$i; 
done

【讨论】:

  • 您仍然可以正确地引用扩展而不扩展 glob:-iname "*.$i"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多