Frage

Sometimes I want to create a duplicate of a number of files (say, config files), which initially should have the same content as the initial files. Therefore I'd like to be able mark some files in dired and "duplicate" them, this duplication procedure could work similar like the duplication procedure utilised by most file managers, when pasting to the original directory: The file names of the duplicated get "(Copy)" appended (just before the file extension).

I can't seem to find a built-in dired function that does this, maybe someone can help/has already created a function like this?

Help is much appreciated!

War es hilfreich?

Lösung 2

Maybe you will want to rename the functions (I didn't come up with better names), maybe some more elaborate formatting, if you wish...

(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)

Also, I've originally used v to bind this function because I don't use dired-view, but you would need to bind that inside direds hook. c just was the first undefined key, so I used it.

Andere Tipps

There is one function that does what you want: dired-do-copy-regexp

Example of use:

  1. mark the files
  2. M-x dired-do-copy-regexp
  3. \(.*\)\.\(.*\)
  4. \1 (copy).\2

For a file named foo.txt you will be creating another named foo (copy).txt

Note that my first regexp has two groups, and the second regexp references them. You can do much more complicated things, if needed.

In the Dired mode, put cursor on the file you want to duplicate or mark that file, then press "C". You will be prompted for new name.

You can use this feature to copy files between Dired buffers as well. To make it possible put into your init file: (setq dired-dwim-target t)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top