Bash: 从函数中查找 -exec

Bash: find -exec from a function

我想使用 bash 函数中的 find -exec。 我知道我需要用 {} \; 终止 -exec,但我找不到正确的方法!

我试过了:

find $SEARCHPATH -name \"${FILEPAT}.[ch]\" -exec grep --color -aHn \"$GREPPATTERN\" {} \;
find $SEARCHPATH -name \"${FILEPAT}.[ch]\" -exec grep --color -aHn \"$GREPPATTERN\" '{}' \;
find $SEARCHPATH -name \"${FILEPAT}.[ch]\" -exec grep --color -aHn \"$GREPPATTERN\" \{\} \;
find $SEARCHPATH -name \"${FILEPAT}.[ch]\" -exec grep --color -aHn \"$GREPPATTERN\" '{}' ';'

还有很多其他的,但我什么都做不了。 大多数时候我得到 find: missing argument to '-exec'find 接受语法时,我没有得到像这样的简单请求的结果:

find . -name "*.[ch]" -exec grep --color -aHn "e" {} \;

有人可以帮我解决这个问题吗? 谢谢!

不要对参数周围的引号进行转义 - 当您这样做时,引号将被视为参数的一部分,例如查找文件名中包含实际引号的文件。使用这样的东西:

f() {
    searchpath=
    filepat=
    greppattern=
    find "$searchpath" -name "$filepat.[ch]" -exec grep --color -aHn "$greppattern" {} \;
}

[编辑] 扩展我对引号被视为参数一部分的评论:命令行中的引号会影响其中文本的解析方式。双引号允许扩展变量引用 ('$varname`) 和其他一些东西,但除此之外别无其他。一旦它们产生了这种效果,它们就会被删除(即它们不会传递给命令本身)。为了看到这一点,让我们定义一个只打印其参数的函数,并查看它实际从各种命令行接收的内容:

$ printargs() { printf "  <%s>\n" "$@"; }
$ printargs one two
  <one>
  <two>
$ printargs "one" "two"  # The quotes will be removed before printargs sees them
  <one>
  <two>
$ printargs "one two"   # The quotes make the two words into one argument, but again aren't passed on to printargs
  <one two>
$ printargs "one" 'two' three   # Single-quotes are also removed
  <one>
  <two>
  <three>

类似的事情发生在变量上:

$ var="one two"   # Note that the quotes are removed before the value is stored in $var
$ printargs $var    # Variable is substituted, then its value is parsed into separate words
  <one>
  <two>
$ printargs "$var"   # Double-quotes here allow the variable to be expanded, but prevent further parsing
  <one two>
$ printargs '$var'   # Single-quotes prevent even variable expansion
  <$var>

但是,如果您对引号进行转义,则它们不会产生任何这些效果;它们只是被视为论点的一部分:

$ printargs \"one\" \'two\' \"three four\"
  <"one">
  <'two'>
  <"three>
  <four">
$ printargs \"$var\"
  <"one>
  <two">

...这几乎不是您想要的。特别是,使用 find 命令:

$ searchpath=.
$ filepat='*'
$ greppattern='#ifdef'
$ printargs "$searchpath" -name "$filepat.[ch]" -exec grep --color -aHn "$greppattern" {} \;
  <.>
  <-name>
  <*.[ch]>
  <-exec>
  <grep>
  <--color>
  <-aHn>
  <#ifdef>
  <{}>
  <;>
$ printargs "$searchpath" -name \"$filepat.[ch]\" -exec grep --color -aHn \"$greppattern\" {} \;
  <.>
  <-name>
  <"*.[ch]">
  <-exec>
  <grep>
  <--color>
  <-aHn>
  <"#ifdef">
  <{}>
  <;>

...在第二个(带有转义引号)中,引号被传递给 find 并将它们视为文件名模式的一部分,查找名称中带有双引号的文件。如果它设法找到任何东西,同样的事情也会发生在 grep 命令上——它会寻找带有双引号的 #ifdef。