2013-07-02 3 views
1

Иногда я хочу создать дубликат нескольких файлов (скажем, файлов конфигурации), которые изначально должны иметь тот же контент, что и исходные файлы , Поэтому я хотел бы отметить некоторые файлы в дурацких и «дублированных», эта процедура дублирования может работать аналогично процедуре дублирования, используемой большинством файловых менеджеров, при вставке в исходный каталог: имена файлов дублированного get " (Копирование) "(непосредственно перед расширением файла).Dired: Duplicate Files (операция, а не как избавиться от них)

Я не могу найти встроенную функцию, которая выполняет это, может быть, кто-то может помочь/уже создал такую ​​функцию?

Помощь очень ценится!

ответ

3

Может быть, вы хотите переименовать функции (я не придумал лучше имена), может быть, некоторые более сложное форматирование, если вы хотите ...

(defcustom dired-keep-marker-version ?V 
    "Controls marking of versioned files. 
If t, versioned files are marked if and as the corresponding original files were. 
If a character, copied files are unconditionally marked with that character." 
    :type '(choice (const :tag "Keep" t) 
     (character :tag "Mark")) 
    :group 'dired-mark) 

(defun dired-version-file (from to ok-flag) 
    (dired-handle-overwrite to) 
    (dired-copy-file-recursive from to ok-flag dired-copy-preserve-time t 
       dired-recursive-copies)) 

(defun dired-do-version (&optional arg) 
    "Search for numeric pattern in file name and create a version of that file 
with that number incremented by one, or, in case such file already exists, 
will search for a file with the similar name, incrementing the counter each 
time by one. 
Additionally, if called with prefix argument, will prompt for number format. 
The formatting is the same as is used with `format' function." 
    (interactive "P") 
    (let ((fn-list (dired-get-marked-files nil nil))) 
    (dired-create-files 
    (function dired-version-file) "Version" fn-list 
    (function 
     (lambda (from) 
     (let (new-name (i 0) (fmt (if arg (read-string "Version format: " "%d") "%d"))) 
      (while (or (null new-name) (file-exists-p new-name)) 
      (setq new-name 
        (if (string-match "^\\([^0-9]*\\)\\([0-9]+\\)\\(.*\\)$" from) 
         (concat (match-string 1 from) 
           (format fmt 
             (+ (string-to-number (match-string 2 from)) (1+ i))) 
           (match-string 3 from)) 
        (concat from (format (concat "." fmt) i))) 
        i (1+ i))) new-name))) 
    dired-keep-marker-version))) 

(define-key dired-mode-map (kbd "c") 'dired-do-version) 

Кроме того, я первоначально использовал v, чтобы связать эту функцию, потому что я не использую dired-view, но вам нужно будет связать ее внутри dired s hook. c только что был первым неопределенным ключом, поэтому я использовал его.

+0

Да! Определенно, очень классный фрагмент! Я подумал о двух дополнениях: 1) Если вызывается с префиксом 'C-u', попросите строку поставить вместо числа и 2) Проверьте, существует ли версия и соответственно увеличиваются. Я не знаю, насколько сложным и трудоемким может быть добавление этих функций .... – elemakil

+0

@elemakil в настоящее время он предложит вам переименовать файл, если только что созданное имя существует ... возможно, может быть автоматическое разрешение, хотя ... Я посмотрю на это позже сегодня. При написании этого фрагмента я обнаружил, что поведение по умолчанию для многих команд 'dired' ... :)' C-u' для них означает, что если есть маркированный каталог, он будет использовать этот каталог в качестве цели. Но, конечно, он может сделать больше с префиксом. Сегодня вечером я буду заниматься этим больше. –

+0

@elemakil хорошо, обе вещи оказались проще, чем я думал. Кажется, что это работает в целом, но если вы заметите какие-либо проблемы с ним, вы можете предупредить меня :) Это не похоже, что эта функция может навредить, поскольку она не удаляет файлы, ни перезаписывает, d все еще будьте осторожны, на всякий случай. –

4

Существует одна функция, которая делает то, что вы хотите: dired-do-copy-regexp

Пример использования:

  1. пометить файлы
  2. M-x dired-do-copy-regexp
  3. \(.*\)\.\(.*\)
  4. \1 (copy).\2

Для файла с именем foo.txt вы создадите другое имя foo (copy) .txt

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

+0

Мне это нравится! Приятно и легко и напоминает мне, что я всегда должен что-то попробовать с регулярными выражениями, прежде чем отправлять вопрос на SO ... ;-) Однако, я думаю, это не может быть расширено, чтобы автоматически обнаружить, есть ли уже (копия) 'present (а не файл, который отмечен), и если это правда, добавляет больше строк '(copy)', пока имя файла не будет уникальным? [Не то, чтобы я действительно использовал это ... ваше начальное решение достаточно, но мне любопытно]. – elemakil

+0

Если вы хотите обработать случай, когда присутствует копия, вы должны взглянуть на переменные 'dired-backup-overwrite' (from dired-aux.el) и' backup-directory-alist'. Первый элемент управления, если вы делаете резервные копии перед перезаписью файлов, позже описывает, как назвать резервные копии. – juanleon

+0

Пункт 3 выглядит как группа болельщиков –