【问题标题】:Looping on empty directory content in Bash [duplicate]在 Bash 中循环空目录内容 [重复]
【发布时间】:2015-07-14 14:40:55
【问题描述】:

我正在编写一个 shell 脚本,我需要在其中循环遍历目录,然后遍历其中的文件。所以我写了这个函数:

loopdirfiles() {
    #loop over dirs
    for dir in "${PATH}"/*
    do
        for file in "${dir}"/*
            do
                echo $file
            done
    done
}

问题在于它会在空目录上回显 *path/to/dir/** 之类的内容。

有没有办法使用这种方法并忽略那些目录?

【问题讨论】:

  • 如果您在脚本中使用PATH 作为变量不要。您将中断正在运行的外部命令,因为 PATH 用于此目的。通常应避免使用 ALL_CAPS 变量(脚本全局变量除外),因为它们是为 shell 的/等“保留”的。使用。

标签: bash loops


【解决方案1】:

您可以打开nullglob option。它会导致不匹配的 glob 扩展为一个空列表,而不是保持未扩展状态。

shopt -s nullglob

【讨论】:

  • 我已经在函数之外设置了这个选项,并给了我相同的结果。
  • 确保您使用的是bash 而不是sh,并确保在您希望使用它的同一个shell 会话中设置它(例如,在您当前的shell 中设置它,然后运行一个具有该功能的脚本不会看到它)。
【解决方案2】:

您可以从目录名称中删除*,而不是完全忽略它:

[[ $file == *"*" ]] && file="${file/%\*/}"
#this goes inside the second loop

或者如果你想忽略空目录:

[[ -d $dir && $ls -A $dir) ]] || continue
#this goes inside the first loop

另一种方式:

files=$(shopt -s nullglob dotglob; echo "$dir"/*)
(( ${#files} )) || continue
#this goes inside the first loop

或者你可以同时打开nullglobEtan Reisner提到的)和dotglob

shopt -s nullglob dotglob
#This goes before first loop.


From Bash Manual

nullglob

如果设置,Bash 允许扩展不匹配文件的文件名模式 到一个空字符串,而不是他们自己。

点球

如果设置,Bash 在结果中包含以“.”开头的文件名 文件名扩展。

注意:dotglob 包括隐藏文件(名称以. 开头的文件)

【讨论】:

  • 在失败的 glob 上运行 ls 以确定 glob 是否失败是为此目的相对昂贵的测试。
  • @EtanReisner,它在第一个循环中,glob 没有失败..
  • 是的。这仍然是测试这种情况的一种相对昂贵的方法,因为失败的 glob 很容易检测到(如果你不只是避免nullglob 的问题)。
  • 第一个为我工作:)
  • @fedorqui 是的,他早了 15 分钟...忘记了...已编辑...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-30
  • 1970-01-01
  • 2016-04-17
  • 2010-12-04
  • 2019-01-22
相关资源
最近更新 更多