find - 如何创建别名来执行类似 (find . -iname '*$1*') 的操作?

find - 如何创建别名来执行类似 (find . -iname '*$1*') 的操作?

我有一个findn功能:

findn () {
    find . -iname "*$1*"
}

使用此函数有一个缺点,如果文件名包含空格,我无法使用-print0 | xargs -0 command(我正在使用 mac)以下findn filename扩展 find 命令的功能。

那么,有没有什么办法可以同时保留方便-iname "*$1*"又实用的功能呢?| xargs command

我正在考虑使用别名来做到这一点,但它不一定是别名。

答案1

您的解决方案适用于xargs

$ echo "foo bar one" > foobarone
$ echo "foo bar two" > fooBARtwo
$ findn "bar"
./fooBARtwo
./foobarone
$ findn "bar" | xargs cat
foo bar two
foo bar one

或者我有什么遗漏的吗?

如果你稍微修改一下你的函数,你可以在你的find命令中添加额外的参数:

findn () {
  local name=$1
  shift
  find . -iname "*$name*" "$@"
}

例子:

$ findn bar ! -name '*two' -print0 | xargs -0 cat
foo bar one

答案2

GNUfind或兼容的一种方法(-iname无论如何已经是 GNU 扩展)可以将函数定义为:

findn() (
  if [ -t 1 ]; then # if the output goes to a terminal
    action=-print  # simple print for the user to see
  else
    action=-print0 # NUL-delimited records so the output can be post-processed
  fi
  first=true
  for arg do
    if "$first"; then
      set -- "$@" '('
      first=false
    else
      set -- "$@" -o
    fi
    set -- "$@" -iname "*$arg*"
    shift
  done
  "$first" || set -- "$@" ')'
  exec find . "$@" "$action"
)

然后您可以将其用作:

findn foo bar

包含foo或的文件名bar(如果需要,请将其更改为上面的文件名,而不是包含两者的文件-o-afoo bar)。

和:

findn foo bar | xargs -r0 cat

如果您想对 . 找到的每个文件应用命令findn

对于兼具这两种功能的变体不是:

findn() (
  if [ -t 1 ]; then # if the output goes to a terminal
    action=-print  # simple print for the user to see
  else
    action=-print0 # NUL-delimited records so the output can be post-processed
  fi
  first=true
  for arg do
    if "$first"; then
      set -- "$@" '('
      first=false
    else
      set -- "$@"
    fi
    if [ "$arg" = ! ]; then
      set -- "$@" !
    else
      case $arg in
        (*[][*?\\]*)
          # already contains wildcard characters, don't wrap in *
          set -- "$@" -iname "$arg"
          ;;
        (*)
          set -- "$@" -iname "*$arg*"
          ;;
      esac
    fi
    shift
  done
  "$first" || set -- "$@" ')'
  exec find . "$@" "$action"
)

进而:

findn foo bar ! baz

foo对于同时包含andbar和 not的文件名baz

在该变体中,我还这样做了,如果参数包含通配符,则按原样采用,因此您可以执行以下操作:

findn foo ! 'bar*'

查找不存在的文件开始与酒吧。如果您使用的是zshshell,则可以创建一个别名:

alias findn='noglob findn'

要禁用该命令的通配符,您可以编写:

find foo ! bar*

您可能希望将其作为一个脚本(这里一个sh脚本就足够了,因为该语法是 POSIX)而不是一个函数,这样就可以从任何地方调用它,而不仅仅是您的 shell。

相关内容