「find」を使用して、「rm」が「-execdir」で実行されたときよりも完全なパス名を印刷するにはどうすればよいですか?

「find」を使用して、「rm」が「-execdir」で実行されたときよりも完全なパス名を印刷するにはどうすればよいですか?

回答のまとめ: 文献では、「-execdir」が「-exec」よりも安全であると宣伝していますが、動作上の違いを無視しないでください。前者は後者の単純な再実装ではない。また、インタラクティブな削除に特別にfindを使用している場合は、「-okdir」オプションを指定して「rm -f」を実行することもできます。やや複雑な構造の場合も同様です。

「find」コマンドを学習しようとしていますが、その出力を理解できません。これが重複した場合はお詫び申し上げます。しかし、問題の説明は少し複雑でグーグルが難しいです。

ペットボックスを設定します。いくつかのディレクトリ(「.」)から始まり、「A」と「B」という2つのサブディレクトリがあります。どちらのファイルにも「hello.c」というファイルがあります。

例えば、

find . -name "hello.c"

次のように印刷されます。

./A/hello.c
./B/hello.c 

今まではそんなに良くなった。 "-execdir"オプションを使用しようとすると迷子になります。インタラクティブな削除を使用したいとしましょう。それから:

find . -name "hello.c" -execdir rm -i {} \;

または同様です。私が期待したのは

rm: remove regular file "./A/hello.c"?

その後、この質問に答えるために、同様の "hello.c"プロンプトが "B"ディレクトリに表示されます。残念ながら、実際に起こっていることは

rm: remove regular file "./hello.c"? 

この小さな例では、「./A/hello.c」を要求していると合理的に推論できますが、この例を拡張すると、パス名が「./」で切り捨てられた数十のファイルが得られます。何十もの "./hello.c"がそれぞれどのサブディレクトリにあるかを区別することはできません。

だから私の質問は、「-execdir」を介してより完全なパス名を印刷したいということです。マンページで私が認識していないいくつかの微妙なことについてのヒントを聞くことはできますか? 「{}」の交換にはほとんど知られていません。あるいは、この特定のケースを管理するためのより良い方法(対話型削除)がある場合は、私のアプローチがベストプラクティスであるかどうかわからないので、聞きたいです。

ベストアンサー1

GNUのマニュアルページではfindこれについて部分的に説明します。-execdir

に似ています-execが、指定されたコマンドは通常、起動したディレクトリではなく一致するファイルを含むサブディレクトリで実行されますfind

したがって、実際の微妙さは含まれません。-execコマンドが実行されているディレクトリからコマンドを呼び出しfind(したがって、そのディレクトリへの相対パスまたはルートの絶対パスを指定する必要があります)、ファイルを-execdir含むディレクトリからコマンドを呼び出すため、提供する必要はありません。フルパスパスなのでそうではありません。

必要な動作を得るには代わりに-exec使用する必要があります-execdir

rm呼び出しをecho単に引数リスト(この場合はファイル名)印刷に置き換えることで、この動作を表示できます。または、-print外部コマンドを呼び出さずにこれを実行するには、whichを使用します。 (注:-print指定されていない場合、これはデフォルトのタスクでもあります。)

確認が不要な場合に-delete機能します。これはrm繰り返し呼び出すのを防ぎ、大量のファイルに対してより効率的になる可能性があります。

おすすめ記事