如何在 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=的文字扩展]
首先,大家好,这是我第一次 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=的文字扩展]