如何在 bash 中的 for 循环中传递具有特定扩展名的文件列表

How to pass a list of files with a particular extension in a for loop in bash

首先,大家好,这是我第一次 post 来这里。 我发誓我已经检查过该网站是否有类似问题以避免 "double post about same argument" 问题,但其中 none 完全回答了我的问题。 问题是,在下面的代码中,当我调用将扩展名作为第一个参数传递给它的脚本时,我总是会收到 "There are no files with this extension" 消息。

#!/bin/bash
if [ "" ];
    then
        file=*."";
        if [ -f "$file" ];
            then
                for i in "$file";
                [...do something with the each file using "$i" like echo "$i"]
            else
                echo "There are no files with this extension";
        fi;
     else
         echo "You have to pass an extension"
     fi;

我尝试使用双括号,在嵌套 if 中使用和不使用引号,在 if 中直接使用 *."",但此解决方案的 none 有效。

一个问题是,当您第一次为 file 赋值时,您 没有 引用变量。在此声明中:

    file=*."";

* 将由 shell 解释,因此例如如果您在命令行中传入 .py,文件可能以值 file1.py file2.py, 这将在稍后抛出您的文件存在性测试。

正如@sideshowbarker 指出的那样,另一个问题是您不能在 [ -f ... ].

中使用通配符

另一个变量引用问题是引用会抑制通配符扩展,这样即使没有文件存在性测试,如果 $file 是,例如 *.txt,那么这个:

for x in "$file"; do ...

将循环遍历具有文字值 *.txt 的单个参数,而此:

for x in $file; do ...

将遍历所有以 .txt 扩展名结尾的文件(除非有 none,在这种情况下它将循环一次 $x 设置为文字值 *.txt).

通常,您会编写脚本以期望参数列表,并允许用户像 myscript *.txt 那样调用它...也就是说,将通配符处理留给交互式 shell,并让您的脚本处理参数列表。那么就变得简单了:

for i in "$@"; do
  echo do something with this file named "$x"
done

如果你真的想在你的脚本中处理通配符扩展,这样的事情可能会奏效:

#!/bin/bash
if [ "" ];
    then
        ext=""
        for file in *.$ext; do
            [ -f "$file" ] || continue
            echo $file
        done
     else
         echo "You have to pass an extension"
     fi;

语句[ -f "$file" ] || continue是必要的,因为我前面提到的情况:如果没有文件,循环仍然会执行一次*.$ext.[=29=的文字扩展]