2016-01-25 14 views
1

В Linux, как мне перемещать файлы без замены, если определенный файл уже существует в пункте назначения?Linux перемещает файлы без замены, если файлы существуют

Я попробовал следующую команду:

mv --backup=t <source> <dest> 

Файл не заменяются, но этот вопрос является расширение получает изменилось, потому что он ставит «~» в конце имени файла.

Есть ли другой способ сохранить расширение, но только имя файла изменяется при перемещении?

E.g. test~1.txt вместо test.txt~1

Когда расширение заменяется, впоследствии вы можете просто просмотреть файл, дважды щелкнув по нему.

+1

Предполагаю, что вы знаете опцию '-n' для' mv'? Это не совсем то, о чем вы просите (потому что он ничего не делает, если место назначения существует), но может быть то, что вам нужно ... –

ответ

1

@aandroidtest: если вы можете полагаться на сценарий Bash оболочки и исходный каталог (где файлы находятся в настоящее время) и целевой каталог (куда вы хотите переместить) - это одна и та же файловая система, я предлагаю вам попробовать сценарий, который я написал.Вы можете найти его в https://github.com/jmmitchell/movestough

Вкратце, скрипт позволяет перемещать файлы из исходного каталога в целевой каталог с учетом новых файлов, дубликатов (одинакового имени файла, одинакового содержимого), конфликтов файлов (таких же имя файла, другое содержимое), а также репликацию необходимых структур подкаталогов. Кроме того, скрипт обрабатывает переименование файлов в трех формах. В качестве примера, если было обнаружено, что /some/path/somefile.name.ext является конфликтующим файлом. Он будет перемещен в целевой каталог с именем, как один из следующих, в зависимости от стиля deconflicting выбранного (через флаг -u= или --unique-style=): стиль

  • по умолчанию: /some/path/somefile.name. ext-< уникальная строка здесь>
  • style 1: /some/path/somefile.name. < уникальная строка здесь> .ext
  • стиль 2:/some/path/somefile. < уникальная строка здесь. .Name.ext

Сообщите мне, если у вас есть вопросы.

4

Если вы хотите сделать это в оболочке, не требуя атомарности (так что если в двух процессах оболочки работает одинаковый код одновременно, у вас могут быть проблемы), вы просто можете (используя встроенную функцию test(1) оболочки)

[ -f destfile.txt ] || mv srcfile.txt destfile.txt 

Если вам требуется атомарность (то, что работает, когда два процесса одновременно запустить его), все довольно сложно, и вам нужно вызвать некоторые системные вызовы в C. Посмотрите в renameat2(2)

Возможно, вам стоит рассмотреть возможность использования некоторой системы контроля версий, например, git?

+0

OP хочет переименовать файлы, не касаясь их расширения. Это не отвечает на вопрос. – Blauhirn

3

mv имеет возможность:

-S, --suffix=SUFFIX 
      override the usual backup suffix 

, которые вы можете использовать; однако afaik mv не имеет функции для изменения части имени файла, но не расширения. Если вы просто хотите, чтобы иметь возможность открыть файл резервной копии с помощью текстового редактора, вы могли бы рассмотреть что-то вроде:

mv --suffix=.backup.txt <source> <dest> 

, как это будет работать: предположим, у вас есть

-rw-r--r-- 1 chris users 2 Jan 25 11:43 test2.txt                                                       
-rw-r--r-- 1 chris users 0 Jan 25 11:42 test.txt 

затем после команды mv --suffix=.backup.txt test.txt test2.txt вы получаете:

-rw-r--r-- 1 chris users 0 Jan 25 11:42 test2.txt                                                       
-rw-r--r-- 1 chris users 2 Jan 25 11:43 test2.txt.backup.txt 
+0

Я уверен, что 'mv' (и подобные инструменты, такие как' cp' и 'ln') никогда не интерпретируют имена файлов. Поэтому он не относится к «.» С каким-либо конкретным значением, и единственным преобразованием, которое он когда-либо будет делать, является добавление суффикса резервного копирования. Это хорошая вещь. Если вы хотите что-то другое, то, скорее всего, выйдет сценарий Bash или Perl. –

+0

@TobySpeight Я не говорю, что mv интерпретирует что-либо. Я говорю, что «afaik mv не имеет возможности изменять часть имени файла, но не расширение». Я добавил пример, иллюстрирующий мое предложение; но я согласен, что это не 100%, чего хотел аандроид. –

+0

Я не спорю - мой комментарий был дополнением к вашему ответу. Просто дополнительная информация для вопросителя для объяснения _why_ 'mv' не может сохранить существующий суффикс. Извините, если оказалось, что я оспариваю ваш ответ! –

1

Удовлетворение команды mv довольно ограничено, если вы перемещаете файлы с одинаковым именем файла.

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

Я изменил сценарий, который можно найти здесь: https://superuser.com/a/313924

#!/bin/bash 
source=$1 
dest=$2 

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

if [[ ! -e "$dest/$basename.$ext" ]]; then 
     mv "$source" "$dest" 
else 
     num=1 
     while [[ -e "$dest/$basename$num.$ext" ]]; do 
      ((num++)) 
     done 
     mv "$source" "$dest/$basename$num.$ext" 
fi 
+0

это требует, чтобы 'dest' был директором. – Blauhirn