4

Я делал это с Хейзел. Я бы переместил все из ~/Downloads/ в ~/Downloads/Archive/Pictures , ~/Downloads/Archive/Documents , ~/Downloads/Archive/Videos и т.д. В зависимости от расширения файла и в случае файла с идентичным именем уже существует, Хейзел просто добавит номер к файлу, который она перемещает.

Я хотел написать сценарий оболочки, который бы достиг этого, но я быстро понял, что понятия не имею, как переименовать файлы без какого-либо пользовательского ввода. Схема для переименования может быть простым счетчиком после имени файла, и она должна иметь место только тогда, когда mv перезапишет существующий файл. Он также должен иметь возможность продолжить счетчик, если уже было множество экземпляров с одинаковым именем файла. Итак, если я переместил dirA/file.ext в dirB/ котором уже есть file.ext и file2.ext , скрипт должен начать считать с 3 и переименовать dirA/file.ext в dirB/file3.ext .

Может ли кто-нибудь предложить какое-либо руководство о том, как добиться этого? Желательно с помощью сценария оболочки, но если нет, то в Ruby, Perl или Python. Просто знание того, возможно ли это с помощью сценария оболочки, поможет мне.

3 ответа3

8

Это не так сложно. Если целевой файл существует, вам просто нужно разбить файл на базовое имя и расширение и увеличивать счетчик до тех пор, пока новое имя файла не появится в целевом каталоге.

source=dirA/file.ext
dest_dir=dirB

file=$(basename file.ext)
basename=${file%.*}
ext=${file##*.}

if [[ ! -e "$dest_dir/$basename.$ext" ]]; then
    # file does not exist in the destination directory
    mv "$source" "$dest_dir"
else
    num=2
    while [[ -e "$dest_dir/$basename$num.$ext" ]]; do
        (( num++ ))
    done
    mv "$source" "$dest_dir/$basename$num.$ext" 
fi 
3

Вы также можете сделать это с помощью одной команды, если на каждой рабочей станции установлена версия mv GNU. По умолчанию, поставляемый с Mac OS X, не поддерживает параметр --backup . Вы можете получить GNU Coreutils для Mac OS X через Macports и во многих других местах.

Тогда это просто вопрос:

mv --backup=numbered dirA/file.ext dirB/

Полученное имя файла будет file.ext.~1~ , file.ext.~2~ и так далее.

0

Благодаря glenn я переписал эту функциональность, чтобы она поддерживала пустые расширения, а также принимала прямые файлы в качестве места назначения (как это делает обычный mv )

mv_no_override() {
    local dir file ext base num
    if [ -d "$2" ]; then
        dir=$2
        file=$(basename "$1")
    else
        dir=$(dirname "$2")
        file=$(basename "$2")
    fi
    ext="$(sed -r 's/.+(\..+)|.*/\1/' <<<"$file")"
    base="$(sed -r 's/(.+)\..+|(.*)/\1\2/' <<<"$file")"
    while [ -e "$dir/$base$num$ext" ]; do
        (( num++ ))
    done
    mv "$1" "$dir/$base$num$ext"
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .