Bash查找:更改匹配的名称以在-exec中使用

时间:2011-11-12 17:59:12

标签: bash shell find

我正在编写一个部署脚本,我需要针对目录中的所有.less文件运行一个较少的编译器。使用以下find命令很容易做到:

find -name "*.less" -exec plessc {} {}.css \;

在包含名为main.less的文件的文件夹上运行此命令后,我留下了一个名为main.less.css的文件,但我希望它为main.css

我知道我可以使用此命令轻松地删除生成的文件的.less部分:rename 's/\.less//' *.css但我希望学习使用-exec的新内容。

在-exec参数中使用它时是否可以修改匹配文件的名称?

谢谢!

2 个答案:

答案 0 :(得分:3)

您的find命令使用了几个非标准的GNU扩展:

  • 你没有说明在哪里找到,这是POSIX中的错误,但GNU find在那种情况下选择当前目录
  • 您使用非隔离{},POSIX查找在这种情况下不会扩展它。

这是一个应该与大多数查找实现一起使用并修复双扩展问题的单行程序:

find . -name "*.less" -exec sh -c "plessc \$0 \$(dirname \$0)/\$(basename \$0 less)css" {} \;

在Solaris 10及更早版本中,如果PATH不符合POSIX,则sh -c应替换为ksh -c

答案 1 :(得分:2)

不,不可能直接这样做。您只能使用{}直接插入完整的文件名。但是,在exec中,您可以使用awk之类的其他内容。或者您可以通过管道将输出重定向到另一个程序。

来自find man页面:

   -exec command ;
          Execute command; true if 0 status is  returned.   All  following
          arguments to find are taken to be arguments to the command until
          an argument consisting of `;' is encountered.  The  string  `{}'
          is  replaced by the current file name being processed everywhere
          it occurs in the arguments to the command, not just in arguments
          where  it  is alone, as in some versions of find.  Both of these
          constructions might need to be escaped (with a `\') or quoted to
          protect  them  from  expansion  by  the shell.  See the EXAMPLES
          section  for  examples  of  the  use  of  the -exec option.  The 
          specified command is run once for each matched file. The command 
          is executed in the starting directory.   There  are  unavoidable
          security  problems  surrounding  use  of  the -exec action;  you
          should use the -execdir option instead.