Как я могу скопировать все мои неорганизованные файлы в один каталог? (на Linux) - PullRequest
1 голос
/ 16 июня 2009

У меня есть тысячи mp3-файлов внутри сложной структуры папок, которая находится в одной папке. Я хотел бы переместить все mp3-файлы в один каталог без подпапок. Я могу придумать множество способов сделать это с помощью команды find, но одной проблемой будут повторяющиеся имена файлов. Я не хочу заменять файлы, так как у меня часто бывает несколько версий одной и той же песни. Авто-переименование будет лучше. Мне все равно, как файлы переименованы.

Кто-нибудь знает простой и безопасный способ сделать это?

Ответы [ 8 ]

6 голосов
/ 16 июня 2009

Вы можете изменить путь 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 голосов
/ 16 июня 2009
#!/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
2 голосов
/ 16 июня 2009

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
1 голос
/ 30 июня 2009

Поскольку вам все равно, как называются дубликаты файлов, используйте опцию 'backup' на ходу:

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

Получит ли ты:

  • Song.mp3
  • Song.mp3. ~ 1 ~
  • Song.mp3. ~ 2 ~
1 голос
/ 16 июня 2009

В 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
1 голос
/ 16 июня 2009

С риском для многих отрицательных голосов, Perl-скрипт может быть написан в короткие сроки для достижения этой цели.

псевдокод:

while (-e filename)
     change filename to filename . "1";
1 голос
/ 16 июня 2009
find /path/to/mp3s -name *.mp3 -exec mv \{\} /path/to/target/dir \;
1 голос
/ 16 июня 2009

Я бы предпочел сделать это простым скриптом, а не пытаться вписаться в одну командную строку.

Например, в python было бы относительно тривиально выполнить walk () по каталогу, копируя каждый найденный mp3-файл в другой каталог с автоматически увеличивающимся номером.

Если вы хотите стать более любопытным, вы можете иметь словарь существующих имен файлов и просто добавить число к дубликатам. (индекс словаря - это имя файла, а значение - количество найденных файлов, которое станет вашим суффиксом)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...