特定の拡張子を持つすべてのファイルを複数のサブディレクトリから1つのディレクトリに移動します


43

複数のディレクトリに多数の.zipファイルがあります。

Fol1/Fol2
Fol3
Fol4/Fol5

それらをすべて共通の基本フォルダーに移動するにはどうすればよいですか?


ディレクトリ構造を保持しますか?ディレクトリを移動するのか、それともzipファイルだけを移動するのか?
ヨルダン

zipファイルを移動したいだけです。ディレクトリについてはあまり気にしません-そのままにしておいても削除しても構いません。
InquilineKea

回答:


55

zipファイルを含むツリーの最上位ディレクトリ(cd …)に移動して、実行します

mv **/*.zip /path/to/single/target/directory

これは、zshでそのまま使用できます。シェルがbashの場合は、shopt -s globstar最初に実行する必要があります(このコマンドをに入れることができます~/.bashrc)。シェルがkshである場合は、set -o globstar最初に実行する必要があります(それをに置きます~/.kshrc)。

または、を使用しますfind。これは、特別な準備なしでどこでも機能しますが、より複雑です。

find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;

後で空のディレクトリを削除する場合は、zshで次を実行します。

rmdir **/*(/^Fod)

bashまたはkshの場合:

rmdir **/*/

削除する空のディレクトリがある限り繰り返します。または、任意のシェルで

find . -depth -type d -empty -exec rmdir {} \;

find上記の最初のコマンドはbashで機能していましたが、機能するようにfind . -nameetcに変更する必要がありました。
ジェフトンプソン

1
@Jeff .はGNU findには暗黙的ですが、他のユーザーにはそうではありません。明示的に追加しました。
ジル 'SO-悪であるのをやめる'

13

.zipファイルを移動するだけの場合は、次のようなことができます

mkdir ./zipfiles
find . -name "*.zip" -exec mv "{}" ./zipfiles \;

3

あなたが使用している場合、bashのバージョン4以上かのzshをあなたはまた、再帰グロブを使用することができます。

mv **/*.zip /path/to/move/zip/files/to

これにより、相対パスではなくファイルのみが移動するため、衝突が発生する可能性があります。


相対パスとはどういう意味ですか?
クノック

2

これは、バージョンに関係なくすべてのディストリビューションのほとんどをサポートするデータおよびエラーのない移動時に安全です。このコマンドは、サブディレクトリをスキャンしてから、新しい宛先ディレクトリに移動またはコピーします。

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • 移動するファイルを含むサブディレクトリを含むメインディレクトリでこのコマンドを実行します。
  • あなたの場合の*.flacようなもの*.zipに変更できる場所。または*.doc、任意の拡張機能が機能します。
  • そしてmvファイルを移動するためのコマンドである、またはあなたが使用することができcp、データをコピーする代わりに移動すること。
  • ./flac/すべてのFLACファイルの移動先のディレクトリです。次のような完全なパスを指定することもできます/home/myid/flac/

完全な例。(この場合、音楽アーティスト名のサブディレクトリが多数/home/myid/Music/あり、FLACファイルはすべて異なるサブディレクトリレベルにあります。アーティストフォルダは必要ないが、すべてのFLACファイルを1つのディレクトリに入れたい/home/myid/Music/flac/

cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls

その後、すべてのFLACファイルが表示されます。


何を;するの?
フランチェスコ・ボイ

@FrancescoBoi同じ行のbashコマンドがジョブを完了するまで待つようにしてください。次に、bashコマンドの次の行に進みます。これは.plやpythonなどのスクリプトを含むコマンドに便利です。bashがそれを実行してから次の行にジャンプするからです。bashがスキップする場合のために、時間またはスクリプトを要するコマンドの後。
Seandex

0

バッシュハックとして、次の機能を使用できますtar

(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/

これには、fileコマンドを使用して移動するファイルを選択し、ディレクトリ構造を保持するため、ファイル拡張子に依存しないという利点がありますが、スペースを含むパスでは機能しません。

最後rmは、元のファイルを削除するためだけです(@InquilineKeaは、コメント内の元のフォルダーを気にしないと言っているため)。

もちろん、これはorigin /およびtarget /フォルダーが異なるディスク上にある場合に特に適しています。それ以外の場合、提案された他のソリューションは(fileコンテンツの代わりに命名規則に依存していても)より効率的です。


0

findとmvのGNUバージョンを持っていると仮定すると、以下は既存の検索ベースの回答よりも効率的です。

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

+find -execの最後でa を使用すると、見つかったファイルごとに1つのmvコマンドを実行するのではなく、ファイルのリストがmvコマンドに渡されます。ただし、これの制限は、コマンドの最後に「{}」しか配置できないことです。これにより、mv --target-directoryオプションの使用が必要になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.