概括

概括

在我的目录树中,某些子文件夹同时包含 *.flac 和 *.mp3 文件,但其他子文件夹仅包含 *.mp3 文件。我想将所有 *.mp3 文件移动到另一个目的地(不同的硬盘驱动器),但前提是该子目录中也存在 *.flac 文件。换句话说,当 *.mp3 没有重复的 *.flac 时,我想保留它们。

有什么建议么?

答案1

概括

解决这个问题的直观方法是:

  1. 递归迭代 mp3 文件列表,
  2. 对于找到的每个 mp3 文件,检查匹配的 flac 文件,
  3. 如果flac文件存在,则将这对文件从源目录移动到目标目录中的相应路径

我已经在 Python 和 Bash 中包含了这个简单算法的基本实现。

Python解决方案

这是一个 Python 脚本,应该可以满足您的要求:

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""move_pairs.py

Move pairs of matching *.mp3 and *.flac files from one directory tree to another.
"""

from glob import glob
import os
import shutil
import sys

# Get source and target directories as command-line arguments
source_dir = sys.argv[1] 
target_dir = sys.argv[2]

# Recursivley iterate over all files in the source directory with a ".mp3" filename-extension
for mp3_file in glob("{}/**/*.mp3".format(source_dir), recursive=True):

    # Create the corresponding ".flac" filename
    flac_file = mp3_file[:-3] + "flac"

    # Check to see if the ".flac" file exists - if so, then proceed
    if os.path.exists(flac_file):

        # Create the pair of target paths
        new_mp3_path = target_dir + "/" + mp3_file.partition("/")[2]
        new_flac_path = target_dir + "/" + flac_file.partition("/")[2]

        # Ensure that the target subdirectory exists
        os.makedirs(os.path.dirname(new_mp3_path), exist_ok=True)

        # Move the files
        shutil.move(mp3_file, new_mp3_path)
        shutil.move(flac_file, new_flac_path)

你可以像这样调用它:

python move_pairs.py source-directory target-directory

为了测试它,我创建了以下文件层次结构:

.
├── source_dir
│   ├── dir1
│   │   ├── file1.flac
│   │   ├── file1.mp3
│   │   └── file2.mp3
│   └── dir2
│       ├── file3.flac
│       ├── file3.mp3
│       └── file4.mp3
└── target_dir

运行脚本后,我得到了以下结果:

.
├── source_dir
│   ├── dir1
│   │   └── file2.mp3
│   └── dir2
│       └── file4.mp3
└── target_dir
    ├── dir1
    │   ├── file1.flac
    │   └── file1.mp3
    └── dir2
        ├── file3.flac
        └── file3.mp3

重击解决方案

下面是 Bash 中几乎相同的实现:

#!//usr/bin/env bash

# Set globstar shell option to enable recursive globbing
shopt -s globstar

# Get source and target directories as command-line arguments
source_dir="$1"
target_dir="$2"

# Recursively iterate over all files in the source directory with a ".mp3" filename-extension
for mp3_file in "${source_dir}"/**/*.mp3; do 

    # Create the corresponding ".flac" filename
    flac_file="${mp3_file%.mp3}.flac"

    # Check to see if the ".flac" file exists - if so, then proceed
    if [[ -f "${flac_file}" ]]; then

        # Create the pair of target paths
    new_mp3_path="${mp3_file/#${source_dir}/${target_dir}}"
    new_flac_path="${flac_file/#${source_dir}/${target_dir}}"

    # Ensure that the target subdirectory exists
    mkdir -p "$(dirname ${new_mp3_path})"

        # Move the files
    mv -i "${mp3_file}" "${new_mp3_path}"
    mv -i "${flac_file}" "${new_flac_path}"

    fi
done

我运行这个脚本如下:

bash move_pairs.sh source_dir target_dir

这给出了与运行 Python 脚本相同的结果。

答案2

如果考虑等价的话,问题会稍微简单一些:对于每个 FLAC 文件,移动同名的 MP3:

shopt -s globstar

targetroot='/path/to/target'
for f in **/*.flac
do 
    dir=$(dirname "$f")
    mp3=$(basename "$f" .flac).mp3
    [[ -e "$dir/$mp3" ]] || continue
    mkdir -p "$targetroot/$dir"
    mv -t "$targetroot/$dir" "$dir/$mp3"
done

相关内容