膨大な数のファイルを日付構造のディレクトリ順にコピーする

膨大な数のファイルを日付構造のディレクトリ順にコピーする

約 40,0000 個のファイルを日付構造のフォルダーにコピーする必要があります。
サンプル ファイル:

/var/public/voicelogging/quality_monitoring/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

コピーする必要がある多くのファイルの1つです/home/username/logging/

ファイル名には、使用する必要がある 2 つの変数が含まれています。

bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

20151209もちろん、日付は
12434ファイルを作成したユーザーの ID です。

必要なのは、ディレクトリ内でユーザー ID を検索できるスクリプト/ワンライナーです。

次に、 のユーザー ID を含むディレクトリを作成します/home/username/logging。フォルダーを作成した後、見つかった日付ごとにディレクトリを作成する必要があります。
そして、 のすべてのファイルを適切なディレクトリに配置しますuserid/date
結果ディレクトリの例。

/home/username/logging/12434/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

日付ディレクトリを作成するためのワンライナーを作成しましたが、ユーザー ID ディレクトリは自分で作成する必要があります。

find /var/public/voicelogging/quality_monitoring/ -type f -name "*12434*" | sed -r 's/^.{65}//' | cut -c1-8 | xargs -I {} mkdir {} /home/username/logging/12434

正しいファイルを正しい場所にコピーするにはどうすればいいでしょうか?

答え1

findおよびを使用した 1 つの方法install:

find /var/public/voicelogging/quality_monitoring -name \*.WAV -exec sh -c '
bn=${0##*/}; x=${bn%%-*}; dt=${x##*_}; y=${bn%_*}; id=${y##*_} 
install -D "$0" "/home/username/logging/${id}/${dt}/${bn}"' {} \;

これはパラメータ展開を使用してファイル名から日付${dt}とユーザーIDを抽出し、次に${id}install各ファイルを対応するディレクトリにコピーしますuserID/date(これは私が怠け者だからです) -install最後の行を次のように置き換えずに:

dest=/home/username/logging/${id}/${dt}; mkdir -p "${dest}" && cp "$0" "${dest}"' {} \;

.WAVこれらの「日付」ディレクトリをループし、各ディレクトリ内のファイルをループしたい場合は、次のようにします。

for d in /var/public/voicelogging/quality_monitoring/*; do
  dt=${d##*/}
  for f in $d/*.WAV; do
    bn=${f##*/}; y=${bn%_*}; id=${y##*_}
    dest=/home/username/logging/${id}/${dt}
    mkdir -p "${dest}" && cp "${f}" "${dest}"
  done
done

を使用するとzsh、より簡単かつ短くなりますzmv(また、zshよりスマートで、変数展開をネストできるため、たとえば、${${file%_*}##*_}ユーザー ID を抽出するのに十分です)。

dtcp () {                                                                     
mkdir -p $3 && cp $1 $2 $3
}
autoload zmv
zmv -n -p dtcp '/var/public/voicelogging/quality_monitoring/(*)/(*).WAV' \
'/home/username/logging/${${2%_*}##*_}/$1'

は、2番目のパラメータでなど(*)として使用できるバック参照を作成します。ここ で、は の代わりに関数を実行します。関数はディレクトリを作成し、ファイルを新しく作成されたディレクトリにコピーします。引数(上記のバック参照と間違えないでください)は次のとおりです。: はオプションの終了を意味します。: はコピーするファイルです。 : はコピー先です。 はを表します。$1$2
zmv-pdtcpmv
$1--

$2/var/public/voicelogging/quality_monitoring/(*)/(*).WAV'

$3/home/username/logging/${${2%_*}##*_}/$1

-n予行演習; コマンドを実際に実行するには削除します。

関連情報