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

发布于 2024-10-04 09:30:20 字数 480 浏览 1 评论 0原文

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

编辑:一种解决方案是查找“$(readlink -f -- "$test_filename")”,但它很难看。还有更好的想法吗?

编辑2:感谢您的建议。以下是由此产生的两个脚本:safe-find.shsafe-count-files.sh

find interprets a dash at the start of a filename as the start of an option. Using the familiar -- trick doesn't work since options are after the filename, quoting has no effect, and replacing the first dash with \- doesn't work either. Users are often encouraged to precede such filenames with ./, but what can I do if I don't know whether the given path will be absolute or relative?

Edit: One solution is to find "$(readlink -f -- "$test_filename")", but it's ugly. Any better ideas?

Edit 2: Thanks for the suggestions. Here are the two scripts that resulted from this effort: safe-find.sh; safe-count-files.sh

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别想她 2024-10-11 09:30:20

这可能看起来有点便宜,但我实际上推荐您已经找到的 readlink 解决方法。根据 Unix 标准

第一个以a开头的参数
'-' (...) 以及所有后续参数
应被解释为
表达式

所以--确实不起作用。 thkala 的解决方案也可能有效,但我发现它的可读性较差。不过,如果您执行大量 find 调用,它可能会更快。

This may seem a bit cheap, but I actually recommend the readlink workaround that you've figured out. According to the Unix standard,

The first argument that starts with a
'-' (...) and all subsequent arguments
shall be interpreted as an
expression

so -- will indeed not work. thkala's solution may also work, but I find it less readable. It may be faster though, if you're doing a lot of find invocations.

懷念過去 2024-10-11 09:30:20

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

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

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

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

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

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

If it is in a script you can always check for it. E.g. for bash, ksh or zsh:

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

In a more terse form (for bash, ksh93 or zsh):

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

You can even do this with the parameters of a script, if they are all supposed to be directories:

find "${@/#-/./-}"
最初的梦 2024-10-11 09:30:20

这是一种适用于所有类 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 "$@" …

1 <子>
readlink -f 可在 GNU(Linux、Cygwin 等)、NetBSD ≥4.0、OpenBSD ≥2.2、BusyBox 上使用。它在 Mac OS X(自 10.6.4 起)、HP-UX 上不可用(除非您已安装 GNU 工具,并且确保它们位于您的 PATH 中) (自 11.22 起)、Solaris(自 OpenSolaris 200906 起)、AIX(自 7.1 起)。

Here is a way that should work on all Unix-like systems, with no requirement on a specific shell or on a non-standard utility¹.

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

If you have a list of directories in your positional parameters and want to process them, it gets a little complicated. Here's a POSIX sh solution:

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

Bourne shells and other pre-POSIX sh implementations lack arithmetic and set --, so it's a little uglier.

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 is available on GNU (Linux, Cygwin, etc.), NetBSD ≥4.0, OpenBSD ≥2.2, BusyBox. It is not available (unless you've installed GNU tools, and you've made sure they're in your PATH) on Mac OS X (as of 10.6.4), HP-UX (as of 11.22), Solaris (as of OpenSolaris 200906), AIX (as of 7.1).

几味少女 2024-10-11 09:30:20

使用 glob 捕获破折号:

find . -name '[-]*'

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

Use a glob to capture the dash:

find . -name '[-]*'

edit: updated to remove the phrase regular expression, and to quote the glob so it's interpreted by find, not bash (only affects some edge cases).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文