で実行するfind
と-execdir
、期待した結果が得られません。
例えば:
mkdir -p a/b/c
find . -type d -execdir touch foo \;
$ tree a
a
├── b
│ ├── c
│ └── foo
└── foo
ディレクトリにファイルc
が含まれていませんfoo
。find
各ディレクトリでローカルにアクセスして何かを行うにはどうすればよいですか?
で実行するfind
と-execdir
、期待した結果が得られません。
例えば:
mkdir -p a/b/c
find . -type d -execdir touch foo \;
$ tree a
a
├── b
│ ├── c
│ └── foo
└── foo
ディレクトリにファイルc
が含まれていませんfoo
。find
各ディレクトリでローカルにアクセスして何かを行うにはどうすればよいですか?
回答:
一致するすべてのファイル(つまり、すべてのディレクトリ)に対して、そのファイルfind
を含むディレクトリ(つまりその親ディレクトリ)に切り替え、指定されたコマンドを実行します。このコマンドは一致の名前を使用しないため、すべてのディレクトリで動作することはありません。この特定のディレクトリツリーでは、次のようにしています。
(cd . && touch foo) # because ./a matches
(cd ./a && touch foo) # because ./a/b matches
(cd ./a/b && touch foo) # because ./a/b/c matches
すべてのディレクトリにファイルを作成する-exec
には-execdir
、引数の内部でallowの実装が提供されている場合、の代わりに単に使用find
でき{}
ます(ほとんどの場合、特にすべてのものを考えます)。
find . -type d -exec touch {}/foo +
POSIXの移植性のために、ディレクトリ名とファイルベース名を手動で組み立てる必要があります。
find . -type d -exec sh -c 'touch "$0/foo"' {} \;
または(少し高速)
find . -type d -exec sh -c 'for d; do touch "$d/foo"; done' _ {} +
または、bashの再帰的なワイルドカードマッチングを使用できます。(kshおよびzshの対応する機能とは異なり、find
コマンドとは異なり)bashはディレクトリへのシンボリックリンクの下で再帰することに注意してください。
shopt -s globstar
for d in **/*/; do touch -- "$d/foo"; done
zshソリューション:
touch ./**/(e\''REPLY+=foo'\')
man bash
「-c」の下の状態:command_stringの後の引数は$ 0で始まる位置パラメーターに割り当てられますが、「for d」は$ 1で始まる位置パラメーターを反復処理します。「_」は、$ 0に割り当てられるテキストであり、使用されません。