使用 xargs 和 find

使用 xargs 和 find

我想从搜索文件中排除一些目录,然后运行 ​​find 命令来查找所需文件。我使用以下命令

find . -maxdepth 1 -type d | grep -E -i 'sensors' | grep -v '.test' | xargs find -name '*.java'

但它会引发以下错误

find: paths must precede expression

答案1

第一个 find 将导致第二个 find 列出所有内容两次,除非您也排除当前目录。发生这种情况的原因是第一个 find 的输出包含句点。

$ find -maxdepth 1 -type d -print0 |
   grep -z -v -Ee 'sensors|\.test' |
   xargs.exe -0 -I% find % -name '*.java' |
   sort
  ./dirz/3.java
  ./dirz/3.java
  ./foo/2.java
  ./foo/2.java
  ./moo/1.java
  ./moo/1.java

你最好做这样的事情:

$ find . -type f -name \*java | grep -v -Ee './(sensors|\.test)'
./dirz/3.java
./foo/2.java
./moo/1.java

甚至:

$ echo dirz foo moo | tr \  \\n  > .search-dirs

$ find `cat .search-dirs` -type f -name \*java
dirz/3.java
foo/2.java
moo/1.java

答案2

使用xargs'-i选项,类似于 的find选项-exec{}用路径替换。

... | xargs -i find "{}" -name '*.java'

答案3

您可以直接在find; 中执行此操作,无需涉及grepxargs

目录结构如下:

$ ls *
a_sensors_directory:
my_file.java  my_non_java_file.txt

a_sensors_directory.test:
my_file.java  my_non_java_file.txt

something_else:
my_file.java  my_non_java_file.txt

,此GNU find命令将在当前工作目录中挑选出.java包含单词的目录中以 结尾的文件sensors,但不以 结尾.test(如果我正确理解了你的问题的话):

$ find -type f -ipath './*sensors*' -not -ipath './*.test/*' -iname '*.java'
./a_sensors_directory/my_file.java

man find应该清楚地解释这些开关,并且可能比我解释得更好。

管道功能强大,但基础工具可以以更直接的方式自行处理许多场景。这可以避免不必要的进程分叉,并将细微错误降至最低。

相关内容