LINUX.ORG.RU

Помогите осилить mv

 


0

1

Хочу переместить содержимое одного каталога в другой. И не выходит.

$ mkdir dir1
$ mkdir dir1/dir
$ touch dir1/dir/file1

$ mkdir dir2
$ mkdir dir2/dir
$ touch dir2/dir/file2

$ mv dir1/* dir2
mv: cannot move ‘dir1/dir’ to ‘dir2/dir’: File exists

Элементарный же пример — и такая неожиданность. Как это сделать?

★★

Ответ на: комментарий от fffgh

Видимо, это и исправлено.

Нет, есть удаленный комментарий, где у переменных local нет.

Скрытые файлы и каталоги перемещает?

Полагаю что нет. Но можно строчку добавить и будет.

только на питоне

Можно почитать?

Tanger ★★★★★
()
Ответ на: комментарий от fffgh

Сперва надо удалить dir2/file, затем переименовать dir1/file. С этим же mv справляется

Мне стало любопытно, и я проверил твой пример. Единственно, что он мне выдал:

mv: cannot move 'dir1/dir' to 'dir2/dir': Directory not empty

ХЗ о чем ты рассуждаешь тут.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от Tanger

move.py

#!/usr/bin/env python3

from os import path, rename, listdir, rmdir
from sys import argv

def move(src, dst):
	if not path.exists(dst):
		rename(src, dst)
	
	elif path.isdir(src) and path.isdir(dst):
		for name in listdir(src):
			move(path.join(src, name), path.join(dst, name))
		if listdir(src) == []:
			rmdir(src)
	
	else:
		print('Warning: will not move {} to {}. {} exists.'.format(src, dst, dst))
	
	return

move(argv[1], argv[2])

move.py dir1 dir2

fffgh ★★
() автор топика
Ответ на: комментарий от tailgunner

mv: cannot move 'dir1/dir' to 'dir2/dir': Directory not empty

Это же та же ошибка? dir1/dir/file1 остался на месте? Вряд ли в разных дистрибутивах mv ведёт себя по-разному.

ХЗ о чем ты рассуждаешь тут.

Что именно ХЗ?

fffgh ★★
() автор топика
Ответ на: комментарий от fffgh

Пояснение: move.py специально не заменяет ничего в dst. Можно было бы заменять файлы на файлы. Или даже файлы на каталоги / каталоги на файлы. Или переименовывать при совпадении имён.

fffgh ★★
() автор топика
Ответ на: комментарий от fffgh

Типа, консоль пока не доросла до решения сложнейшей задачи объединения каталогов? Что-то сомневаюсь.

Нет. Это ты пока что не дорос до решения таких задач. Но не волнуйся, это не сложно, достаточно научиться включать голову и читать.

Black_Shadow ★★★★★
()
Ответ на: комментарий от Black_Shadow

Но не волнуйся, это не сложно, достаточно научиться включать голову и читать.

Ну расскажи, как это делают «научившиеся включать голову и читать».

fffgh ★★
() автор топика
Ответ на: комментарий от fffgh

Это же та же ошибка?

mv: cannot move 'dir1/dir' to 'dir2/dir': Directory not empty

mv: cannot move ‘dir1/dir’ to ‘dir2/dir’: File exists

Выглядит как одна ошибка? По-моему, нет.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Выглядит как одна ошибка? По-моему, нет.

Ну так ты посмотрел, что произошло?

ls dir1/dir

ls dir2/dir

Если результат отличается от моего, то в чём это было запущено?

fffgh ★★
() автор топика

напомните, rsync умеет удалять из источника?

targitaj ★★★★★
()
find dir1/dir -type f -exec mv "{}" dir2/dir \; && rmdir dir1/dir

В самом начале также можно было

mkdir -p dir1/dir dir2/dir
touch dir1/dir/file1 dir2/dir/file2

saahriktu ★★★★★
()
Последнее исправление: saahriktu (всего исправлений: 1)
Ответ на: комментарий от saahriktu
find dir1/dir -type f -exec mv "{}" dir2/dir \;

Ну это ж просто 'mv dir1/dir/* dir2/dir'. Конечно это сработает, но не перебирать же вручную все каталоги.

В самом начале также можно было

mkdir -p dir1/dir dir2/dir

touch dir1/dir/file1 dir2/dir/file2

Ага, спасибо.

fffgh ★★
() автор топика
Ответ на: комментарий от fffgh

но не перебирать же вручную все каталоги

Достаточно указать find'у начальную точку, и он переместит все вложенные файлы. А пустые директории потом можно почистить итерациями команды

find dir1 -type d -exec rmdir "{}" \;

ЗЫ. Для надёжности в реальных условиях можно перемещать файлы так:

yes n | find dir1 -type f -exec mv -i "{}" dir2 \;

saahriktu ★★★★★
()
Последнее исправление: saahriktu (всего исправлений: 2)

Помогите осилить mv

mv - довольно низкоуровневая команда. Когда ты ее используешь, пробуй представить что ее аргументы - узлы ФС, просто иноды каких-то фс. У нее даже нет --recursive! Ей нет дела до того, что находится вне тех узлов, которые ты ей указал. И когда mv манипулирует на таком примитивном уровне с ФС, она иногда получает отлуп от ФС по всяким, вот таким как ты описал, причинам.

Аналогий можно кучу привести. Хороший ли dd редактор файлов? Хороший ли nc веб-сервер?

Deleted
()
Ответ на: комментарий от darkenshvein

dir1 исчез

с чего бы ему исчезать, если указали переносить только подкаталоги?

Да, неправильно написал. dir1 не исчез, а пуст. Исчез dir1/dir, и в dir2/dir лежит file1.

fffgh ★★
() автор топика
Ответ на: комментарий от record

Будешь копировать в каталог с файлами, используй --backup=numbered

Да, будет полезно.

fffgh ★★
() автор топика
Ответ на: комментарий от Deleted

Напомните, почему не подходит rsync -a --delete

rsync же копирует, а не перемещает.

--delete

А это ещё зачем? Совсем не нужно.

fffgh ★★
() автор топика
Ответ на: комментарий от Deleted

mv - довольно низкоуровневая команда. ...

Благодарю за пояснения.

fffgh ★★
() автор топика
Ответ на: комментарий от saahriktu

Да, это просто перемещение файлов с потерей иерархии директорий. Тем не менее, файлы перемещаются.

Ну то есть это решение другой задачи. Тем не менее, это тоже может пригодиться.

fffgh ★★
() автор топика
Ответ на: комментарий от fffgh

да, наверно я поспешил rsync советовать, хотя сам юзаю. Просто, я не люблю семантику перемещения использовать повседневно: чуть что пойдет не так, и у тебя неопределенное состояние. Что там переместилось, что нет - хз.

Я mv использую, когда точно понятно, прям ясно, что будет перемещен узел фс с одного места на другой, что бы место вдруг не исчерпалось, ни чего еще.

–delete

удобная вещь, в контексте копирования каталогов, еще ‘-u’ ок. Ну это наверно оффтоп

Deleted
()
Ответ на: комментарий от fffgh

Какой «другой»? Была задача переместить файлы из одной директории в другую. Это её решение. А сохранение структуры директорий - это дополнительное условие этой задачи. Для выполнения которого нужны более сложные инструменты чем просто find и mv.

saahriktu ★★★★★
()
Ответ на: комментарий от Deleted

чуть что пойдет не так, и у тебя неопределенное состояние. Что там переместилось, что нет - хз.

В моём случае наоборот будет удобно. Заглянул в dir1 — там то, что не ушло в dir2. Сразу видно, как сработало.

--delete

удобная вещь, в контексте копирования каталогов

Возможно, но мне ничего из dir2 удалять не надо.

fffgh ★★
() автор топика
Ответ на: комментарий от dikiy

mv '{}' '../dir2/{}'

Так не будет же работать...

$ mkdir -p src/bar dst
$ touch src/1 src/bar/2
$ cd src ; find -type f | xargs -I {} mv '{}' '../dst/{}'
mv: cannot move './bar/2' to '../dst/./bar/2': No such file or directory

P.S. зачем ты тут используешь xargs если у find есть exec?

Tanger ★★★★★
()
Ответ на: комментарий от saahriktu

Была задача переместить файлы из одной директории в другую. Это её решение. А сохранение структуры директорий - это дополнительное условие этой задачи.

Ок, ок. Дополнительное условие: с сохранением структуры директорий.

Иначе, возможно, файлы сами себя затирать начнут, при совпадении имён.

Для выполнения которого нужны более сложные инструменты чем просто find и mv.

Люди выше сочиняют всякие одно- и много- строчники из этих find и mv.

fffgh ★★
() автор топика
Ответ на: комментарий от Tanger

P.S. зачем ты тут используешь xargs если у find есть exec?

чтобы в перпективе сделать все за один вызов mv, и не вызывать для каждого файла новый процесс.

dikiy ★★☆☆☆
()
Ответ на: комментарий от Tanger

Так не будет же работать...

у меня на твоем примере изначальном сработало...

dikiy ★★☆☆☆
()
Ответ на: комментарий от fffgh

Иначе, возможно, файлы сами себя затирать начнут, при совпадении имён.

Нет. Для этого и введена структура

yes n | ... mv -i
mv с опцией -i начинает работать в интерактивном режиме, в случае совпадения имён спрашивая у юзера перезаписывать ему старый файл новым или нет. А вместо юзера здесь уже yes, который каждый раз отвечает «нет, не перезаписывать». В итоге файлы с совпадающими именами останутся на своих местах. И их можно будет переместить следующей итерацией в другую директорию.

saahriktu ★★★★★
()
Ответ на: комментарий от dikiy

чтобы в перпективе сделать все за один вызов mv

С сохранением структуры директорий? как?

у меня на твоем примере изначальном сработало...

Я не ТС.
я ему вначале предложил воссоздать структуру директорий, затем переместить файлы.

Но тут будут терятся, например, владельцы и права доступа. Есть идеи как без «наркоманства» решить такую задачу на bash?

Tanger ★★★★★
()
Ответ на: комментарий от dikiy

но вообще судя по всему, если начинать юзать diff, то в результате получится все равно rsync :)

поэтому можно сразу делать rsync и не париться:

rsync -a --link-dest=$PWD/dir1/ dir1/ dir2/

rsync создасть жесткие ссылки где можно и не будет копировать лишний раз. А потом просто можно будет снести dir1 целиком.

Tanger

dikiy ★★☆☆☆
()
Последнее исправление: dikiy (всего исправлений: 1)
Ответ на: комментарий от Deleted

Напомните, почему не подходит rsync -a --delete и тема еще не закрыта?

подходит, просто надо заставить его хардлинки делать вместо копирования.

dikiy ★★☆☆☆
()
Ответ на: комментарий от dikiy

чтобы в перпективе сделать все за один вызов mv, и не вызывать для каждого файла новый процесс.

А слабо man xargs на предмет -I прочитать что ли?

Ну и это делается и find-ом, при замене "-exec ;" на "-exec +". Вот только и в том и в другом случае для двух '{}' это логически не возможно.

vodz ★★★★★
()
Ответ на: комментарий от dikiy

rsync создасть жесткие ссылки где можно и не будет копировать лишний раз.

Но оно будет работать только в пределах одной ФС.

Хотя можно сделать проверку на то в разных ли оно fs..

dev1="$(df dir1/  | tail -n 1 | cut -f1 -d" ")"
dev2="$(df dir1/  | tail -n 1 | cut -f1 -d" ")"
if [ "$dev1" = "$dev2" ]; then
    rsync -a --link-dest=$PWD/dir1/ dir1/ dir2/
else
    rsync -a dir1/ dir2/
fi
# rm -rf dir1/

P.S. похоже что касты при редактировании не работают - уведомление не пришло.

Tanger ★★★★★
()
Ответ на: комментарий от Tanger

есть вероятность, что rsync и так отработает и просто если нельзя сделать hard link, скопирует файлы. Надо пробовать.

dikiy ★★☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.