サブディレクトリ内のすべてのファイルを再帰的に単一のディレクトリに移動するにはどうすればよいですか?


10

現在のディレクトリの下のすべてのファイルとすべてのサブディレクトリを1つのディレクトリに収集しようとしています。私は次のようなものを試しています

find -type f -exec mv {} collection/{} \; 

上記のコマンドは、2番目{}が完全なパスを与えるため機能しません。どうすればすべてのファイルを収集できますか?

回答:


14

{}fromを削除するとmvmv親ディレクトリを無視してそれをターゲットディレクトリとして取得します。

find -type f -exec mv {} collection/ \;

ああ、それは私には起こりませんでした。おかげで:)
バニーウサギ

質問への私の回答で言うように、これは潜在的に悪い考えです。たぶん、引数を使用すること-maxdepth 1が役立つでしょう。
loevborg、

考えてみてください、私はあなたの質問を間違って読んだようです:)すみません。
loevborg、

@loevborg:タイトルに「再帰的に」追加しました。それでも混乱がある場合は、編集して改善してください:)
Lekensteyn

1
この回答のより速いバリエーションはfind -type f -print0|xargs -0r mv -it colection/
2014年

5

find(うまくいく)を使う代わりに、この目的のためにシェルを使うこともできます。

$ PWDから$ DESTまでのすべてのファイルが必要だとします。自然な試みは次のとおりです。

mv $PWD/* $DEST

これはどのように作動しますか?「$ PWD / *」という表現は、そのディレクトリ内のすべてのファイルの名前に展開されます。このシェル機能は「グロビング」と呼ばれます。の最後の引数mvは宛先ディレクトリです。ファイルが非常に多い場合、コマンドラインの長さが制限されているため、これは機能しません。

しかし、解決策には、ドットファイル、または名前が「。」で始まる「非表示」ファイル、ファイル、およびディレクトリが省略されるという問題があります。これを解決するには、グロビング時にドットファイルを含めるようにシェルに指示する必要があります。これを行うには、

shopt -s dotglob

使用するときbash(そしてbash、デフォルトを変更していない限り、おそらく使用します)。このシェルでは、上記のコマンドはドットファイルでも機能します。

余談zshですが、では、ケースバイケースでこれを選択するオプションがあります。これを行うには、

setopt extendedglob

あなたの.zshrc。その後、使用できます

mv $PWD/*(D) $DEST

dotfilesを含むすべてのファイルを移動します。(「D」には、「GLOB_DOTS」オプションを一時的に有効にする効果があります)。

元の問題は、すべての通常のファイル(ディレクトリではない)をすべてのサブディレクトリとそのサブディレクトリから単一のディレクトリに移動することでした。これは次の方法で実現できますzsh

mv $PWD/**/*(D.)

ここでは、式**/*はglobberをサブディレクトリに再帰的に下降させます。D「dotfilesも選択する」という意味、「.ディレクトリではなく、通常のファイルのみを選択する」という意味です。


よく私はすべてのサブディレクトリにも再帰したかったのですが、情報が役立つ方法のおかげで、この状況に何度も遭遇します:)
バニーウサギ

実際には、findはこれに過剰ではありません。グロビングは、ファイルだけでなくディレクトリもすべての一致を選択します。パフォーマンスが心配な場合は、次のようなものも使用できますfind -type f -exec mv -t collection/ {} +。これがどのように機能するかについては、マニュアルページを参照してください。
Lekensteyn、

Lekensteyn、あなたは正しい。質問を理解したので、答えを更新しました。
loevborg、

2
素晴らしい答えですが、あまり問題が多いので、質問とはあまり関係がありません:)。
crazy2be
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.