web-dev-qa-db-ja.com

ランダムなフォルダーをコピーするためのスクリプト

私はいつも念頭に置いていた小さなプロジェクトを実現したいと思います。デスクトップには膨大な音楽ライブラリがあり、ランダムな量のフォルダー(25枚のアルバムなど)を選択し、可能であればそれらを車のUSBドライブにコピーする方法/スクリプトを探しています。私の完全なビジョンは、次の手順を実行できるスクリプトです。

  1. USBドライブを消去します(音楽にのみ使用されます)
  2. アルバムのランダム選択(データ量の上限?固定数?)
  3. 選択範囲をUSBドライブにコピーします

これは簡単なスクリプトで実行できますか?いくつかの音楽オーガナイザーがこのオプションを持っていたことを覚えていますが、ヘッドレスサーバーのよりシンプルなものを探していました。

6
Seb

以下のスクリプトが仕事をするはずです:

#!/usr/bin/env python3
import random
import os
import subprocess
import shutil

# set the desired number of folders to pick below
n_selection = 5
# set the name of the flash drive below
flashdr = "Lexar"
# set the source directory (with media folders) below
sourcedr = "/path/to/mediafiles"
# ---

try:
    targetdr = [l.split("part ")[-1] for l in subprocess.check_output("lsblk")\
                .decode("utf-8").splitlines()if l.endswith(flashdr)][0]
except IndexError:
    pass
else:
    # empty the flash drive
    for item in os.listdir(targetdr):
        obj = os.path.join(targetdr, item)
        try:
            shutil.rmtree(obj)
        except NotADirectoryError:
            os.remove(obj)
    # list the source dirs
    srclist = []
    for dr in  os.listdir(sourcedr):
        fullpath = os.path.join(sourcedr, dr)
        if os.path.isdir(fullpath):
            srclist.append([dr, fullpath])
    # copy the files
    for picked in random.sample(srclist, n_selection):
        shutil.copytree(picked[1], os.path.join(targetdr, picked[0]))
        srclist.remove(picked)

Source-directoryの最初のサブレベルからターゲットのフラッシュドライブにディレクトリをコピーします。

再帰的フォルダーのコピー、ランダムは、フォルダーサイズとサブレベル数に大きな違いをもたらすため、これが最も理にかなっているようです。それにもかかわらず、私はそれをこの答えの一番下の2番目のオプションとして追加しました。

使い方

  1. スクリプトを空のファイルにコピーし、create_mediausb.pyとして保存します
  2. ヘッドセクションで、選択するファイルの数、フラッシュドライブのname(スクリプトがそのパスを見つける)、およびフォルダーを含むソースディレクトリを設定します。
  3. 次のコマンドを使用してスクリプトを実行します。

    python3 /path/to/create_mediausb.py 
    
  4. すべてが正常に機能する場合は、ショートカットキーに追加します。[システム設定]> [キーボード]> [ショートカット]> [カスタムショートカット]を選択します。 「+」をクリックして、コマンドを追加します。

    python3 /path/to/create_mediausb.py 
    

2番目のオプション:再帰的選択

#!/usr/bin/env python3
import random
import os
import subprocess
import shutil

n_selection = 5
flashdr = "Lexar"
sourcedr = "/home/jacob/Bureaublad/GW_site_nafestival_2015/pix/general"

try:
    targetdr = [l.split("part ")[-1] for l in subprocess.check_output("lsblk")\
                .decode("utf-8").splitlines()if l.endswith(flashdr)][0]
except IndexError:
    pass
else:
    # empty the flash drive
    for item in os.listdir(targetdr):
        obj = os.path.join(targetdr, item)
        try:
            shutil.rmtree(obj)
        except NotADirectoryError:
            os.remove(obj)
    # list the source dirs
    srclist = []
    for root, dirs, files in os.walk(sourcedr):
        for dr in dirs:
            srclist.append([dr, os.path.join(root, dr)])
    # copy the files
    for picked in random.sample(srclist, n_selection):
        shutil.copytree(picked[1], os.path.join(targetdr, picked[0]))
        srclist.remove(picked)

スクリプト:

  1. フラッシュドライブへのパスを検索します。

    try:
        targetdr = [l.split("part ")[-1] for l in subprocess.check_output("lsblk")\
                    .decode("utf-8").splitlines()if l.endswith(flashdr)][0]
    except IndexError:
        pass
    

    フラッシュドライブが見つからない場合は、ここで終了します

  2. ドライブが見つかった場合、空になります

    # empty the flash drive
    for item in os.listdir(targetdr):
        obj = (targetdr+"/"+item)
        try:
            shutil.rmtree(obj)
        except NotADirectoryError:
            os.remove(obj)
    
  3. 次に、適切な選択をランダムに行うために全体ディレクトリリストが必要なので、選択を行う前にリストを作成します。

    # list the source dirs
    srclist = []
    for dr in  os.listdir(sourcedr):
        fullpath = sourcedr+"/"+dr
        if os.path.isdir(fullpath):
            srclist.append([dr, fullpath])
    
  4. 最も興味深い部分は、選択を行うことです。ランダムなディレクトリを選択し、リストからそれを削除して二重選択を防止し、次に別のディレクトリをランダムに選択して削除し、必要な選択の数に達するまで続けます。

    # copy the files
    for picked in random.sample(srclist, n_selection):
        shutil.copytree(picked[1], os.path.join(targetdr, picked[0]))
        srclist.remove(picked)
    
7
Jacob Vlijm

findとshufを使用できます:

#!/bin/bash

SOURCE="path/to/source"
DESTINATION="path/to/destination"
COUNT=25

rm -r "${DESTINATION}/"*
find "$SOURCE" -mindepth 2 -maxdepth 2 -type d|shuf -n $COUNT|xargs -d'\n' -I{} cp -r "{}" "$DESTINATION"
7
user448115

Pythonでスクリプトを作成しました。

GitHub Gistのスクリプトダウンロード

使用法:

python3 RandomCopier.py [source folder] [destination folder] [number to copy]

コピー方法:

注:ソースフォルダー内のファイルを直接コピーしますnot、サブフォルダー内のファイルのみをコピーしますそれの。

ソースフォルダーのsrcは次のとおりです。

src
|- a
|  |- file_a
|  |- file_a_2
|
|- b
|  |- file_b
|
|- c
|  |- file_c
|
|- file_src

次に、宛先フォルダーdestは、次のように2つのフォルダーがランダムにコピーされます。

dest
|- a
|  |- file_a
|  |- file_a_2
|
|- c
|  |- file_c
1