代码之家  ›  专栏  ›  技术社区  ›  srmark

如何将所有无序文件复制到一个目录中?(Linux上)

  •  1
  • srmark  · 技术社区  · 15 年前

    我在一个复杂的文件夹结构中有数千个MP3,它驻留在一个文件夹中。我想将所有MP3移动到一个没有子文件夹的目录中。我可以想出各种方法来做这个 find 命令,但有一个问题是文件名重复。我不想替换文件,因为我经常有同一首歌的多个版本。自动重命名最好。我真的不在乎这些文件是如何重命名的。

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

    8 回复  |  直到 15 年前
        1
  •  6
  •   ephemient    15 年前

    你可以换一个 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
    

    在壳里没有 ${//} 替代:

    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的 cp mv 可以进行编号备份而不是覆盖--请参见 -b / --backup[=CONTROL] 在手册页上。

    find srcdir -name '*.mp3' -exec cp -v --backup=numbered {} dstdir/ \;
    
        2
  •  2
  •   Glen    15 年前

    类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
    
        3
  •  2
  •   mateusza    15 年前
    #!/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
    
        4
  •  1
  •   Kena    15 年前

    我倾向于在一个简单的脚本中完成这项工作,而不是尝试在一个命令行中适应。

    例如,在python中,在目录中执行walk()相对比较简单,将找到的每个MP3文件复制到具有自动递增数字的不同目录中。

    如果你想更进一步,你可以有一个现有文件名的字典,只需在副本上附加一个数字。(字典的索引是文件名,值是到目前为止找到的文件数,这将成为您的后缀)

        5
  •  1
  •   Aaron Maenpaa    15 年前
    find /path/to/mp3s -name *.mp3 -exec mv \{\} /path/to/target/dir \;
    
        6
  •  1
  •   belgariontheking    15 年前

    冒着许多否决的风险,可以在短时间内编写一个Perl脚本来完成这一任务。

    Pseudocode:

    while (-e filename)
         change filename to filename . "1";
    
        7
  •  1
  •   Agathe    15 年前

    在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
    
        8
  •  1
  •   Greg Bender    15 年前

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

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

    会得到你:

    • 歌曲MP3
    • 歌曲MP3~1
    • 歌曲MP3~2