ループと変数で find と grep を使う方法は?

ループと変数で find と grep を使う方法は?

私のディレクトリにはたくさんのファイルがあります。

# ls -1
file1
file2
file3
file4
file5
file6
file7
file8
file9
file10

仕事は次のより古いものを見つけることですfile5。私はこれを行うことができます

# find . ! -newer file5
./file1
./file2
./file3
./file4
./file5

これで、上記の内容の一部/すべてへの参照を含むファイルが作成されました。

# logfile=log
cat ${logfile}
/var/log/app/file1
/var/log/app/file3
/var/log/app/file5

これで、file5よりも古いログファイルにあるファイルのリストだけが欲しいです。結果のリストは次のとおりです。

file1
file3
file5

このようなファイル名からファイル名を見つけようとしましたが、うまくいきませんでした。

find . ! -newer file4 -exec bash -c 'for i in {}; do grep $i ${logfile}; done' \;

ベストアンサー1

/var/log/appこれにより、ディレクトリが代わりにfind . ! -newer file5実行されますfind /var/log/app ! -newer /var/log/app/file5。このfindように出力はlog

findその後、次のいずれかを使用して出力をフィルタリングできますgrep

find /var/log/app ! -newer /var/log/app/file5 | grep -xFf log

-xgrep行全体が一致するようにします。-Fパターンを固定文字列として処理するように指示します。-f指定されたファイルからパターンを読み込みます。これらのオプションは移植可能です。

代わりに(または/var/log/app現在の作業ディレクトリではないがそのようなふりをしたい場合)、2番目のログを作成して、そのエントリが./…元の作業ディレクトリの一般形式と一致するようにしますfind

sed 's|^/var/log/app/|./|' log > log2

新しいログには、find元のコマンド出力をフィルタリングするために使用できる相対パスが含まれています。

find . ! -newer file5 | grep -xFf log2

メモ:

  • ! -newer file5「より年齢が多い」という意味ではありませんfile5。このテストはfile5同じように古いファイルと一致します。
  • 追加のオプション/テスト(例-maxdepth 1:)-type fが役に立ちます。

あなたの試み:

find . ! -newer file5 -exec bash -c 'for i in {}; do grep $i ${logfile}; done' \;

多くの点で欠けている、または次善策:

  • ログファイルはデータで、パス名はパターンと見なされますfind。上記のように、その逆の場合も簡単です。
  • 内部文脈では、bashおよび$i${logfile}引用されません。二重引用符で囲む必要があります。
  • シェルコードを挿入しました{}。通常、埋め込みは{}引用符なしの変数のように動作しますが、どのように引用してもコマンド注入の脆弱性。だからもっと悪いです。
  • (代わりに)1つのパス名を-exec … \;whichに変更しましたが、まだ多くのパス名を予想したように書きました。通常、内部シェルは置き換える内容を2つ以上の単語として解釈できます。ファイル名の生成がトリガーされることもあります。これは上記の「引用符なしの変数のような」動作です。したがって、一般的に循環的な「パス名」が多く発生する可能性がありますが、予想したものとは異なります。{}-exec … {} +for i in {}{}
  • logfile環境にないため、内部シェルは$logfile空の文字列に展開されます。シェルが拡張したくありません(埋め込みに似た欠陥が原因で問題が発生します{})。

おすすめ記事