web-dev-qa-db-ja.com

別のフォルダーに異なるファイルを移動する

OK、それで私は非常に大きなiTunesライブラリを持っていて、最近それを整理して整理することに決めました。すべての音楽をフォルダに入れて最高のものを期待するだけではありません。何時間もファイルを出し入れしたり、ディレクトリを移動したりして、iTunesがiTunesの機能を実行するのを待っていたのですが、どういうわけかいくつかの曲が欠けていました。 1か2だったとしたら、自分で見つけることができます。しかし、私は30000を少し超えているので、手動でそれらを探すことにはあまり熱心ではありません。

だから私の質問は、「Linux環境で、1つのディレクトリにあり、別のディレクトリにないすべてのファイルを見つけて、移動する方法はありますか?」ということです。

私のフォルダ構造は次のようになります:

  • 親ディレクトリ(外付けハードドライブ)

    • ファイルがありません(これらのフォルダーが4つあります
      • アーティスト名の付いた何百ものフォルダ(一部には.mp3ファイルがあり、他には別のサブフォルダがあり、他には別のサブフォルダがある)
    • 親iTunesディレクトリ(iTunesが音楽、プレイリストファイル、ポッドキャストなどを保持する場所)

(私はこれらの質問のリストが本当に得意ではありません^)だから、私が必要なのは、isが "Missing Files"ディレクトリにあるis n'tで移動することです「iTunesフォルダ」

事前の助けてくれてありがとう、本当に感謝しています。

注:mp3ファイルのみをフォルダーから移動し、フォルダー自体は移動しません。

2
Zachary Wight

次のようなディレクトリ構造があるとします。

music
  |- source
      |- foobar
      |- spamegg
      |- ...
  |- dest

また、すべての.mp3ファイルをmusic/source/の任意のレベルのサブディレクトリの下にあるmusic/dest/に移動する必要があるのは、ファイルがmusic/dest/に存在しない場合のみです。

その場合、music/ディレクトリから以下のすべてのコマンドを実行します

  • .mp3の下にあるすべてのmusic/sourceファイルを含む配列を作成し、再帰的な操作を行います。

    shopt -s globstar  ## Enables recursive search
    source_files=( source/**/*.mp3 )
    
  • music/dest/ディレクトリでも同じことを行い、ディレクトリ名の部分をファイル名から取り除きます。

    dest_files=( dest/**/*.mp3 )
    dest_files=( ${dest_files[@]} )
    
  • ソースファイルを反復処理し、ファイルが宛先に既に存在するかどうかを確認します。存在しない場合は、mvからmusic/dest/

    for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && \
             echo mv -i "$i" dest/; done 
    

    echoは、予行演習を行うためのものです。問題がなければ、echoを削除してください。

    for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && \
             mv -i "$i" dest/; done
    

スクリプト形式:

#!/usr/bin/env bash
shopt -s globstar
source_files=( source/**/*.mp3 )
dest_files=( dest/**/*.mp3 )
dest_files=( ${dest_files[@]} )
for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && \
     mv -i "$i" dest/; done

絶対パスを使用して、必要に応じて関連パスを変更できます。

警告:

  • すべてのソースとデスティネーションの.mp3ファイルは配列に入れられ、追加のメモリが少し必要です。最新のシステムでは問題になりません

  • メンバーシップテストには時間がかかりますが、最新のシステムでは目立ちません。

例:

music$ tree 
.
├── dest
│   ├── 1.mp3
│   ├── 2.mp3
│   ├── 3.mp3
│   ├── 7.mp3
│   ├── 8.mp3
│   └── 9.mp3
└── source
    ├── bar
    │   ├── 10.mp3
    │   ├── 6.mp3
    │   ├── 7.mp3
    │   ├── 8.mp3
    │   └── 9.mp3
    └── foo
        ├── 1.mp3
        ├── 2.mp3
        ├── 3.mp3
        ├── 4.mp3
        └── 5.mp3

music$ shopt -s globstar

music$ source_files=( source/**/*.mp3 )

music$ dest_files=( dest/**/*.mp3 )

music$ dest_files=( ${dest_files[@]} )

music$ for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && echo mv "$i" dest/; done
mv source/bar/10.mp3 dest/
mv source/bar/6.mp3 dest/
mv source/foo/4.mp3 dest/
mv source/foo/5.mp3 dest/

music$ for i in "${source_files[@]}"; do [[ ! ${dest_files[@]} =~ ${i##*/} ]] && mv "$i" dest/; done

music$ tree 
.
├── dest
│   ├── 10.mp3
│   ├── 1.mp3
│   ├── 2.mp3
│   ├── 3.mp3
│   ├── 4.mp3
│   ├── 5.mp3
│   ├── 6.mp3
│   ├── 7.mp3
│   ├── 8.mp3
│   └── 9.mp3
└── source
    ├── bar
    │   ├── 7.mp3
    │   ├── 8.mp3
    │   └── 9.mp3
    └── foo
        ├── 1.mp3
        ├── 2.mp3
        └── 3.mp3
1
heemayl