moth Asked: 2021-10-19 19:33:11 +0800 CST2021-10-19 19:33:11 +0800 CST 2021-10-19 19:33:11 +0800 CST 在 bash 或 zsh 中循环一个文件扩展名或另一个文件扩展名 772 这在语法上是正确的: for f in *bw;do echo $f;done 但是我将如何添加一个扩展来循环遍历一个或另一个? 以下不起作用: for f in *bw|*txt;do echo $f;done 这也不起作用: for f in *bw or *txt;do echo $f;done bash zsh 2 个回答 Voted cas 2021-10-19T20:39:25+08:002021-10-19T20:39:25+08:00 你没有。您遍历两个“扩展”并(如果需要)检查其中一个或两者是否存在。例如,如果您只想打印一个或另一个(第一个看到的),请保留每个文件的基本名称(不带扩展名)的列表 - 关联数组对此很有用,因为它很容易查找。例如在 bash 中: declare -A files for f in *.bw *.txt; do bn=${f%.*} if [ -z "${files[$bn]}" ] ; then echo "$f" files["$bn"]=1 fi done Best Answer Michael Homer 2021-10-19T20:59:36+08:002021-10-19T20:59:36+08:00 在 Bash, withshopt -s extglob和 zsh中KSH_GLOB启用: for f in *.@(bw|txt) 请注意,在 bash 中,如果没有匹配项,则循环将运行并$f设置为文字 string *.@(bw|txt)。为了避免这种情况,在 bash 中: shopt -s nullglob for f in *.@(bw|txt) 在 zsh 中,默认情况下,如果没有匹配项,您将收到错误消息。为避免这种情况,请添加N glob 限定符。 for f in *.@(bw|txt)(N) 在 zsh中,有一个更简单的解决方案可以使用默认选项,(N)如果没有匹配项,则再次不执行任何操作: for f in *.(bw|txt)(N) 所有这些都将按字母顺序排列所有条目,两个扩展名混合在一起的文件(即,仅在扩展名上不同的重复名称将(可能¹)是连续的)。您可以根据需要在括号中列出尽可能多的用管道分隔的模式条目,并且它们可以包含更多的 glob(例如(zip|tar.?z))。 ¹foo.bw foot.bw foot.txt foo.txt但是,将在.排序算法中在第一个实例中被忽略的语言环境中按该顺序排序,这在当今很常见(如footborfoott之前footx和之后foobw)。
你没有。您遍历两个“扩展”并(如果需要)检查其中一个或两者是否存在。例如,如果您只想打印一个或另一个(第一个看到的),请保留每个文件的基本名称(不带扩展名)的列表 - 关联数组对此很有用,因为它很容易查找。例如在 bash 中:
在 Bash, with
shopt -s extglob
和 zsh中KSH_GLOB
启用:请注意,在 bash 中,如果没有匹配项,则循环将运行并
$f
设置为文字 string*.@(bw|txt)
。为了避免这种情况,在 bash 中:在 zsh 中,默认情况下,如果没有匹配项,您将收到错误消息。为避免这种情况,请添加
N
glob 限定符。在 zsh中,有一个更简单的解决方案可以使用默认选项,
(N)
如果没有匹配项,则再次不执行任何操作:所有这些都将按字母顺序排列所有条目,两个扩展名混合在一起的文件(即,仅在扩展名上不同的重复名称将(可能¹)是连续的)。您可以根据需要在括号中列出尽可能多的用管道分隔的模式条目,并且它们可以包含更多的 glob(例如
(zip|tar.?z)
)。¹
foo.bw
foot.bw
foot.txt
foo.txt
但是,将在.
排序算法中在第一个实例中被忽略的语言环境中按该顺序排序,这在当今很常见(如footb
orfoott
之前footx
和之后foobw
)。