我想从搜索文件中排除一些目录,然后运行 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
; 中执行此操作,无需涉及grep
或xargs
。
目录结构如下:
$ 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
应该清楚地解释这些开关,并且可能比我解释得更好。
管道功能强大,但基础工具可以以更直接的方式自行处理许多场景。这可以避免不必要的进程分叉,并将细微错误降至最低。