web-dev-qa-db-ja.com

検索から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)
8
Simon Legg

短い答え:

一連の行を別のコマンドの引数として渡すだけの場合は、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"

私のマシンでこれを実行すると、これはファイルが見つかった場所にファイルを提供しているようです。私の脳は疲れているので、それを素敵なスクリプトで包む代わりに(これは、onelinersが危険になり始めたときに実際に行う必要があることであり、 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\""

2
Spike

zshの場合:

projects=(server/lib/**/*(D.:t:r))
grep -rFl --exclude-dir=node_modules -e${(u)^projects} .
  • **/再帰的グロビング。 90年代初頭にzshによって導入された機能。
  • (D.:t:r)はグロブ修飾子であり、zsh固有の機能であり、名前以外の属性を使用してファイルを選択したり、ソートを変更したり、見つかったファイルを変更したりできます。
  • Dfindと同様に、ドットファイルを含めてドットディレクトリをトラバースします。ほとんどの場合、あなたはそれをはずしたいと思うでしょう。
  • .:通常のファイルのみ(find-type fなど)
  • :t:rcsh/bashのような履歴修飾子ですが、ここではグロブファイルに適用されます。 :tは末尾(ベース名)、:rはルート名(拡張子は削除)です。
  • x${^array}は、rcx^$arrayまたはfishx$arrayが行うような要素を配布します。たとえば、$arrayが(12)の場合。それはx1x2になります。
  • ${(u)array}uniqueの場合)、重複を削除します((u)はパラメーター展開フラグです)。

文字列のnoneを含むファイルのリストについては、-l-Lで置き換えます(GNU grepと仮定しますが、すでにGNU-を使用しています)ここに特定のオプションがあります。-Fは固定文字列検索用です(おそらく、これらのプロジェクト名を正規表現として扱わないようにする必要があります)。grep-wオプションをWordが一致するため、たとえばfoofoobarでは一致しません(ただし、foo-barでは一致します)。

6