質問: macでサブフォルダ内のファイルを親フォルダに集める操作を行いたいと考えています。次の記事を参考にしました。 [Mac] サブフォルダ内のファイルを親フォルダに集める【フラット化のコマンド】 下に示したコマンドを実行しようと考えています。 ``` find . -mindepth 2 -type f -exec mv -i '{}' . ';' ``` 前半の `find . -mindepth 2 type f` はカレントディレクトリ内で、2階層までのファイルを検索し、後半の `-exec mv -i '{}' . ';'` は検索したファイルをカレントディレクトリに移動している操作だと理解したのですが、後半の `{}` と `;` を `''` で囲う意味がよく理解できません。 質問は以下の3つです。 1. `{}` と `'{}'` は動作として異なるのか 2. `;` と `';'` は動作として異なるのか 3. `';'` と `\;` は同じ意味なのか 以上です。教えていただけると嬉しいです。よろしくお願いします。
回答: man find によると `{` や `}` や `;` は シェルにとって特別な文字なので `find` を起動しようとしたシェル (`bash` とか `zsh` とか `dash` とか) が先に処理してしまい `find` に渡されないから、適切にエスケープしないといけないよとあります。オイラの知る posix shell すべてで `;` は複文の意味になるので `;\` または `';'` と書く必要があります。 では `{}` のほうはどうかというと `{}` だけではシェルの特殊処理が起動されないので `find` の引数としては `'{}'` と書かなくてもいいことになっています。 `${PS1}` のように書くと環境変数の展開になるのですが。 `find` が見つけたファイル名にスペースが入っているとき `find . -exec mv {} .. \;` と書いたなら、ファイル名 `a qucik brown fox` に対して `mv a quick brown fox ..` のように展開されてしまうと、ファイル名 `a quick brown fox` がシェルによって `a` と `quick` と `brown` と `fox` に分割されてしまいそうに見えます。が、やはりオイラの知る限りの `find` は `{}` の結果(に空白類が含まれていても)1つの `argv` として渡してきます。なのでやはり `{}` を `'{}'` と書かなくてもよいようです。 が、まあ超絶古い商用 UNIX では `find` がバグっているかもしれないので安全のために `'{}'` と書きたがる人がいたような気がしなくもないっス。ウチの hpux11.11 の `/usr/bin/find` でも問題ないので今どき気にするほどのことは無さそうです。