从 find 到 grep 的管道

从 find 到 grep 的管道

我想做什么?

编写一个命令来查找项目中任何其他文件不需要的任何文件。

我尝试了什么?

我用来find获取文件名列表。现在我想使用文件名作为搜索字符串(而不是要搜索的文件)。

我用来find server/lib -type f -exec basename {} \; | cut -f 1 -d '.'获取文件名列表并去掉文件扩展名。

现在我知道这grep -R --exclude-dir=node_modules <search-string> . -l就是我想要将每个文件名通过管道传输到的内容,但我不知道如何将它们作为参数传递<search-string>


其他信息

我还隐约意识到,管道grep可能会传递(整个文件列表)的整个结果find,我显然不想这样做,如果这就是我要做的,然后告诉我。

另外,(尽管这可能不在这个问题的范围内)因为我使用它作为查找任何grep找不到任何内容的文件名的方法,所以任何有关获取此类输出的建议将不胜感激

> <the-command>

filename1
server/lib/foo.js # where these are the list of files in which it appears
test/lib/foo.js

filename2
Not Found! #where `filename2` wasn't found anywhere (obviously)

答案1

zsh

projects=(server/lib/**/*(D.:t:r))
grep -rFl --exclude-dir=node_modules -e${(u)^projects} .
  • **/递归通配符。zsh90 年代初引入的一项功能。
  • (D.:t:r)是一个 glob 限定符,一个zsh特定的功能,允许使用名称以外的属性选择文件,或者更改排序或对找到的文件进行修改。
  • D:包括点文件并按原样遍历点目录find。最有可能的是,你想把那一件脱掉。
  • .:仅常规文件(-type ffind
  • :t, :r: 历史修饰符与csh/类似,bash但此处应用于通配文件。:t为尾部(基本名称),:r为根名称(已删除扩展名)。
  • x${^array}rc像'sx^$arrayfish'sx$array那样分布元素。例如如果$array是( 1, 2)。那就变成了x1 x2
  • ${(u)array}(对于unique),删除重复项((u)作为参数扩展标志)。

对于包含的文件列表没有任何字符串,替换-l-L(假设 GNU grep,但您已经在此处使用 GNU 特定选项)。-F用于固定字符串搜索(因为您可能不希望这些项目名称被视为正则表达式)。您可能还想添加一个-w选项grepfor单词匹配,例如foo不匹配foobar(但仍会匹配foo-bar)。

答案2

简短回答:

如果您只想将一堆行作为参数传递给另一个命令,那么xargs您的朋友就是您的朋友 - 在这种情况下,因为您将其放入命令的中间,所以您将需要使用该-I {}标志。这设置{}为占位符,以便您可以放在任何地方(您可以设置自己的占位符,但我通常坚持使用,{}因为它不会被误认为是许多其他东西。

将它们放在一起(假设您给出的命令按照您的想法执行!):

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} grep -R --exclude-dir=node_modules {} . -l

长答案

好的,我们或许可以更进一步。假设您想要前面提到的格式 - 您可以xargs这样做sh -c,以便可以链接命令:

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} sh -c "echo {}; grep -R --exclude-dir=node_modules {} . -l"

在我的机器上运行这个,看起来这给了你文件所在的文件成立。我的大脑很累,所以不要把它包装在一个漂亮的脚本中(当单线开始变得粗糙时,你实际上应该这样做,并使用https://www.shellcheck.net/当你在做的时候)你可以用这个可怕的黑客来代替,(我认为)这会给你你正在寻找的输出:

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} sh -c "echo {}; grep -R --exclude-dir=node_modules {} . -l && printf \"\n\" || printf \"Not found\n\n\""

相关内容