find -exec で、現在のファイルを {} に置き換えるにはどうすればよいでしょうか?

find -exec で、現在のファイルを {} に置き換えるにはどうすればよいでしょうか?

私が所有していない(つまり、変更する権限がない)すべてのファイルを見つけたいのですが、

find . -exec if [[ ! -O {} ]]; then echo {}; fi ;

ただし、次のようにコマンド全体を引用符で囲むと-exec

find . -exec 'if [[ ! -O {} ]]; then echo {}; fi' \;

どちらも機能しません。現在のファイルへの参照が{}引用符で囲まれているため、ファイルに展開されないためです。

問題は、現在のファイルを単純な例( を 1 回だけ使用する) よりも{}複雑なものに埋め込む方法がわからないことです。現在のファイルを複数回参照するコマンドで、検索オプションを使用するにはどうすればよいでしょうか? (より多くの時間がかかります)。-execfind . -exec grep smf {} \;{}-exec{}

答え1

find実行するように要求したユーティリティif(シェル構文のキーワード) が存在しないため、コードは機能しません。

-O引数が現在のユーザーが所有するファイルである場合、テストは真になります。同じテストは、次のように実行できます(find現在-user "$USER"$USERユーザーに展開されると仮定)。

find . -type f ! -user "$USER"

test -O外部testユーティリティが非標準テストをサポートしている場合は、以下を使用することもできます(チェックman test)。

find . -type f ! -exec test -O {} \; -print

-Oそれでもシェルに組み込まれたテストを使用する必要がある場合は、テストを実行するためにシェルbashを生成する必要があります。bash

find . -type f -exec bash -c '[[ ! -O "$1" ]]' bash {} \; -print

これにより、見つかったファイルごとに 1 つのインラインbash -cスクリプトが開始され、最初の引数 ( ) でテストが実行されます$1。引数は、スクリプトのコマンド ラインで によって渡されますfind(bash前の文字列はスクリプト内{}に配置され$0、そのシェルによってエラー メッセージに使用されます)。テストが true (ファイルが自分の所有物ではない) の場合、-printが有効になり、ファイルのパス名が出力されます。

これをもう少し効率的に行うには

find . -type f -exec bash -c '
    for pathname do
        [[ ! -O "$pathname" ]] && printf "%s\n" "$pathname"
    done' bash {} +

これは、見つかったパス名のバッチをスクリプトに渡すため、より効率的ですbash -c

...しかし、 を使用する方-user "$USER"がより良い選択肢です。

参照:

関連情報