findコマンドを効率的に使用するには?私を助けてくれますか?

findコマンドを効率的に使用するには?私を助けてくれますか?
find ~ -name delete_me -type f -print0 | xargs -0 /bin/rm -f

Q1.どういう意味-print0で、なぜ必要なのですか?

Q2.なぜ/bin/rm?なぜできないのですrm -fか?

このコマンドは、~ディレクトリから一致するファイルのみを削除し、サブディレクトリまたはサブディレクトリから一致するファイルを削除しません。

Q3.サブディレクトリでも一致するすべてのファイルを見つけて削除するように変更するにはどうすればよいですか?

Q4.特定のディレクトリが見つからないように変更するには?

ありがとう

答え1

  1. 非標準-print0述部は、「改行文字ではなく終了ヌル文字で見つかったファイルのパス名を印刷する」という意味です。これは改行文字を含むファイル名を処理できるようにするためです(Unixシステムでは許可されていますが、nul文字はUnixファイル名の一部にはできません)。find使用されたコマンドの出力を読み取るコマンドは、-print0エントリがnullで終了することに注意してください。この-0オプションを使用すると、xargsnull で終わる項目を読み取ることができます。

    これは必須ではありません。どちらもありません

    find "$HOME" -name delete_me -type f -delete
    

    もう標準ではありません。

    find "$HOME" -name delete_me -type f -exec rm {} +
    

    これら2つのコマンドは-print0コマンドと同じことを行い、デフォルトで使用する必要がありますxargsxargsこのユーティリティは、ファイルまたは他のコマンドからパラメータを読み取るときに便利です。ご使用の際には、find内蔵された施設を利用することが-execより安全です。そこはい同時展開を開始するユーティリティなど、特定の実装でxargs実行できるタスクと実行できないタスクがあります。-execただし、この演習ではこの方法は使用されません。

    変数のように動作するので、シェルスクリプトで使用する方が良いですが、"$HOME"そうではありません。~$HOME~

    また、この-fオプションは必要ない場合があります。ユーティリティをrm避けるために使用されます。rm失敗する(診断メッセージと非ゼロ終了ステータスを含む)指定されたパス名が存在しないか、rm削除するパス名なしで呼び出される場合。また、古い-i(対話型モード)オプションをオーバーライドします。ただし、ここのコマンドライン-iにはオプションがなく、そのパスを見つけるために使用されたrmパス名が存在することがfind保証されています(ファイルが実行中に他のプロセスによって実際に削除される競合状態がない限り、削除find実行者によって)findrmfind

  2. 変数値に合理的なユーティリティパスセットが含まれているという保証がない限り、フルパスを使用するrm理由はありません。PATH破損は一般的ではなく、PATH絶対パスを使用してユーティリティを作成するスクリプトは、他のシステムに移動すると簡単に破損する可能性があります。

  3. 実際には、ホームディレクトリのすべてのサブディレクトリで繰り返しました。

  4. 検索ツリーから避けたいディレクトリを削除します。たとえば、次のような名前のすべてのディレクトリを避けるにはavoid:

    find "$HOME" -name avoid -prune -o -name delete_me -type f -exec rm {} +
    

    深さ優先検索を-delete意味するため、ここでは使用できません。-depth深さ優先検索では、ディレクトリが検索ツリーから削除される必要があるavoidことを知る前に、その中のすべてのサブディレクトリとファイルにアクセスします。avoid

    別の例:入力しないでください特定目次$HOME/dir/save_me:

    find "$HOME" -path "$HOME/dir/save_me" -prune -o -name delete_me -type f -exec rm {} +
    

答え2

Q1.-print0は何を意味し、なぜ必要なのですか?

良い出発点は、マニュアルを確認することです。端末に入力するとman find詳細な説明が表示されます。通常、Googleで「man find」を検索して、ウェブ上の同じ/類似のマニュアルページを取得することもできます。

find マニュアルには次のように記載されています-print0

標準出力にフルファイル名を印刷し、その後にヌル文字(-printで使用される改行文字の代わりに)を印刷します。これにより、find 出力を処理するプログラムが改行またはその他の種類のスペースを含むファイル名を正しく解釈できます。

したがって、これは各ファイル名の後にヌル文字を書き、xargsは各-0エントリがで終わると予想して読みます-0

Q2.なぜ/bin/なぜですか?なぜrm -fだけを使用しないのですか?

あなたの質問によると、これがなぜ行われるのかは明らかではありません。

ここには妥当な理由がないようです。時々これが行われる理由の1つは、次のことを許可することです。環境変数が正しく設定されていません。これはコマンドを実行するときに一般的ですcron

ただし、この場合、他のコマンド(findおよびxargs)が正規化されていないため役に立ちません。それが必要です:

 /bin/find ~ -name delete_me -type f -print0 | /usr/xargs -0 /bin/rm -f

もう1つ(可能性がほとんどない)唯一の理由は、システムに2つの異なるrmコマンドがあり、どのコマンドを指定する必要があるかです。しかし、その可能性はほとんどありません。

Q3.サブディレクトリでも一致するすべてのファイルを見つけて削除するように変更するにはどうすればよいですか?

もうそうしました。

Q4.特定のディレクトリが見つからないように変更するには?

この-pruneオプションを使用して、このディレクトリ(およびそのサブディレクトリ)をスキップできます。

# Just editing your version...
find "$HOME" -name exclude_this_dir -prune -o -name delete_me -type f -print0 | xargs -0 /bin/rm -f

# More succinctly
find "$HOME" -name exclude_this_dir -prune -o -name delete_me -type f -exec rm -f {} +

関連情報