如何将所有无组织的文件复制到一个目录中? (在linux上)

时间:2009-06-16 17:05:14

标签: bash shell

我在一个复杂的文件夹结构中有数千个mp3,它位于一个文件夹中。我想把所有的mp3都移到一个没有子文件夹的目录中。我可以想到使用find命令执行此操作的各种方法,但一个问题是重复的文件名。我不想替换文件,因为我经常有同一首歌的多个版本。自动重命名是最好的。我真的不在乎如何重命名文件。

有谁知道一种简单而安全的方法吗?

8 个答案:

答案 0 :(得分:6)

复制后,您可以将a/b/c.mp3路径更改为a - b - c.mp3。这是Bash的解决方案:

find srcdir -name '*.mp3' -printf '%P\n' |
    while read i; do
        j="${i//\// - }"
        cp -v "srcdir/$i" "dstdir/$j"
    done

在没有${//}替换的shell中:

find srcdir -name '*.mp3' -printf '%P\n' |
    sed -e 'p;s:/: - :g' |
    while read i; do
        read j
        cp -v "srcdir/$i" "dstdir/$j"
    done

对于不同的方案,GNU的cpmv可以进行编号备份而不是覆盖 - 请参阅手册页中的-b / --backup[=CONTROL]

find srcdir -name '*.mp3' -exec cp -v --backup=numbered {} dstdir/ \;

答案 1 :(得分:2)

像伪代码一样bash:

for i in `find . -name "*.mp3"`; do
    NEW_NAME = `basename $i`
    X=0
    while ! -f move_to_dir/$NEW_NAME
        NEW_NAME = $NEW_NAME + incr $X

    mv $i $NEW_NAME
done

答案 2 :(得分:2)

#!/bin/bash
NEW_DIR=/tmp/new/

IFS="
"; for a in `find . -type f `
    do
    echo "$a"
    new_name="`basename $a`"
    while test -e "$NEW_DIR/$new_name"
            do
            new_name="${new_name}_"
            done
    cp "$a" "$NEW_DIR/$new_name"
    done

答案 3 :(得分:1)

我倾向于在一个简单的脚本中执行此操作,而不是尝试适合单个命令行。

例如,在python中,通过目录执行walk()是相对简单的,将发现的每个mp3文件复制到具有自动递增数字的不同目录。

如果你想获得更好的,你可以拥有现有文件名的字典,只需在重复项上附加一个数字即可。 (字典的索引是文件名,值是到目前为止找到的文件数,这将成为你的后缀)

答案 4 :(得分:1)

find /path/to/mp3s -name *.mp3 -exec mv \{\} /path/to/target/dir \;

答案 5 :(得分:1)

冒着许多downvotes的风险,可以在短时间内编写perl脚本来完成此任务。

伪代码:

while (-e filename)
     change filename to filename . "1";

答案 6 :(得分:1)

在python中:要实际移动文件,请更改debug = False

import os, re
from_dir="/from/dir"
to_dir = "/target/dir"
re_ext = "\.mp3"
debug = True

w = os.walk(from_dir)
n = w.next()
while n:
    d, arg, names = n
    names = filter(lambda fn: re.match(".*(%s)$"%re_ext, fn, re.I) , names)
    n = w.next()
    for fn in names:
        from_fn     = os.path.join(d,fn)
        target_fn   = os.path.join(to_dir, fn)
        file_exists = os.path.exists(target_fn)
        if not debug:
            if not file_exists:
                os.rename(from_fn, target_fn)
            else:
                print "DO NOT MOVE - FILE EXISTS ", from_fn
        else:
            print "MOVE ", from_fn, " TO " , target_fn

答案 7 :(得分:1)

由于您不关心如何命名重复文件,请使用移动时的“备份”选项:

find /path/to/mp3s -name *.mp3 -exec mv --backup=numbered {} /path/to/target/dir \;

会得到你:

  • Song.mp3的
  • Song.mp3的。〜1〜
  • Song.mp3的。〜2〜