私のディレクトリにはたくさんのファイルがあります。
# 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
-x
grep
行全体が一致するようにします。-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
空の文字列に展開されます。シェルが拡張したくありません(埋め込みに似た欠陥が原因で問題が発生します{}
)。