web-dev-qa-db-ja.com

execを使用すると、cpコマンドでワイルドカードが機能しない

すべてのディレクトリ内のすべてのファイルを親ディレクトリにコピーしたいのですが、エラーが発生します

./img/* is not a directory

例えば。これが私が使用したコマンドです。これを行うためのより良い方法はありますか?

find . -type d -regex './[a-z]*' -exec cp -v {}/* .. \;
4
m0meni

試してみてください:

find . -type d -regex './[a-z]*' -exec bash -c 'cp -v "$1"/* ..' Cp {} \;

討論

考えてみましょう:

find . -type d -regex './[a-z]*' -exec cp -v {}/* .. \;

Bashはこの行を見ると、{}/*でパス名の展開を実行します。 (通常){}という名前のディレクトリがないため、*はリテラル*として残されます。これはあなたが望むものではありません。パス名の展開を行う必要がありますfind{}の代わりになりました。 cpコマンドを引用符で囲み、それを引数としてbash -cに渡すことで、その目標を達成します。

bash -cのサンプルフォームは次のようになります。

bash -c 'code...' a b c 

これは、bashにa$0に、b$1に、c$2に割り当ててから、code...を実行するように指示します。エラーが発生した場合、シェルは実行中のプログラムの名前として$0を使用します(エラーメッセージ内)。上記では、わかりやすい名前としてCpを選択しました。また、上記のように、{}$1の代わりに使用され、$1ではusecode...を使用します。このように使用する場合、{}を引用する必要はありません(ただし、引用しても問題はありません)。 findは、必要なエスケープを処理します。ただし、code...内では、Wordの分割とパス名の拡張から保護するために、$1を二重引用符で囲む必要があります。

4
John1024

これもうまくいくかもしれません

cd your_directory
cp -rp * /absolut_path_to_parent_directory
1
ryder