代码之家  ›  专栏  ›  技术社区  ›  l0b0

在以破折号开头的目录中查找

  •  10
  • l0b0  · 技术社区  · 14 年前

    find 将文件名开头的破折号解释为选项的开头。使用熟悉的 -- 技巧不起作用,因为选项在文件名之后,引用无效,并将第一个破折号替换为 \- 也不管用。通常鼓励用户在这些文件名之前加上 ./ ,但如果我不知道给定路径是绝对路径还是相对路径,我该怎么办?

    编辑:一个解决方案是 find "$(readlink -f -- "$test_filename")" ,但是很难看。有更好的主意吗?

    编辑2 :谢谢你的建议。以下是这项工作产生的两个脚本: safe-find.sh ; safe-count-files.sh

    4 回复  |  直到 14 年前
        1
  •  5
  •   Fred Foo    14 年前

    这看起来有点便宜,但我真的推荐 readlink 你已经找到了解决办法。根据 Unix standard ,

    第一个以 “-”(…)和所有后续参数 应解释为 表达

    所以 -- 确实行不通。thkala的解决方案也可能有效,但我发现它不太可读。如果你做了很多 find 召唤。

        2
  •  6
  •   Gilles 'SO- stop being evil'    14 年前

    如果它在脚本中,您可以随时检查它。例如,对于bash、ksh或zsh:

    if [[ "$DIR" = -* ]]; then
        find ./"$DIR"
    else
        find "$DIR"
    fi
    

    以更简洁的形式(用于bash、ksh93或zsh):

    find "${DIR/#-/./-}"
    

    如果脚本的参数都应该是目录,那么您甚至可以使用它们来执行此操作:

    find "${@/#-/./-}"
    
        3
  •  3
  •   Rufflewind    9 年前

    这是一种在所有类Unix系统上都可以工作的方法,不需要特定的shell或非标准实用程序。

    case $DIR in
      -*) DIR=./$DIR;;
    esac
    find "$DIR" …
    

    如果您的位置参数中有一个目录列表,并且想要处理它们,那么它会变得有点复杂。这里有一个POSIX sh解决方案:

    i=1
    while [ $i -le $# ]; do
      case $1 in
        -*) x=./$1;;
        *) x=$1;;
      esac
      set -- "$@" "$x"
      shift
      i=$(($i + 1))
    done
    find "$@" …
    

    Bourne shell和其他POSIX之前的sh实现缺少算术和 set -- ,所以有点难看。

    i=1
    while [ $i -le $# ]; do
      x=$1
      case $1 in
        -*) x=./$1;;
      esac
      set a "$@" "$x"
      shift
      shift
      i=`expr $i + 1`
    done
    find "$@" …
    

    ¹ readlink -f 可在GNU(Linux、Cygwin等)、NetBSD–4.0、OpenBSD–2.2、BusyBox上使用。它是不可用的(除非您已经安装了GNU工具,并且您已经确保它们在您的 PATH )在MacOSX(从10.6.4开始)、HP-UX(从11.22开始)、Solaris(从OpenSolaris200906开始)、AIX(从7.1开始)上。

        4
  •  0
  •   Alex Brown    10 年前

    使用球捕捉短划线:

    find . -name '[-]*'
    

    edit:更新以删除短语正则表达式,并引用glob,以便由find而不是bash解释(仅影响某些边缘情况)。