Как вы безопасно перемещаете файлы вверх на один каталог?

10

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

То, как обращаться с обманщиками, будет различным, иногда мы перезаписываем, иногда нам нужно быть безопаснее. IO может быть важным, потому что это производственные серверы. Но данное количество подсказок для неповторяющихся файлов не вариант. Сохранение разрешений, временных меток и т. Д. Имеет важное значение. Обычно мы не знаем, что это за данные.

Ох, и это mvне требуется rsync, cpрешения приветствуются.

примечание: мы работаем с CentOS 5.5, поэтому дайте мне знать, если он не будет работать, потому что это более новая функция ...

xenoterracide
источник
Что бы ты хотел делать с дураками?
@ В зависимости от ситуации? Я работаю на веб-хостинге ... это действительно зависит от mvтого, заботимся ли мы о сохранении в случае ... и сделали ли мы уже резервную копию. Этот вопрос довольно открытый. Я просто ищу хорошие варианты и, возможно, комментарий о том, может ли он укусить вас и как.
ксенотеррацид
Я предполагаю, что слишком много файлов для оболочки, чтобы обрабатывать mv * ../или mv -i * ../?
Михаил Мрозек
@ Майкл, я уверен, что это меняется ... в некоторых случаях, вероятно, нет. В некоторых случаях возможно. Я пытаюсь найти как можно больше вариантов для моей работы.
ксенотеррацид

Ответы:

6

Я бы порекомендовал использовать rsync от родителя:

rsync -avPr -b --suffix='-original' child/* .

который создаст резервную копию всех существующих дубликатов в родительском файле в файл -original.

Tok
источник
Я думаю, -aподразумевает-r
ксенотеррацид
@xenoterracide - Верно, что ты
Ток
@ То есть возможно ли сделать копии как жесткие ссылки? чтобы не тратить впустую IO. (как -lдля cp)
ксенотеррацид
@xenoterracide - вы можете использовать -Hили --hard-linksфлаги для rsync для сохранения жестких ссылок.
Ток
1
@xenoterracide - Вы можете использовать этот --link-dest=DIRфлаг для достижения этого поведения следующим образом: он rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/будет жестко связывать dst / любые неизмененные файлы между src и src, в данном случае все файлы. Обычно вы видите, что этот флаг используется, когда вы хотите повторно связать резервные файлы без копирования их данных, таких как --link-dest=/most/recent/backup.
Ток
4
cp -bal . ..

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

после того

rm -rf . ; cd .. ; rmdir <originaldir>;
xenoterracide
источник
вероятно, возникает проблема с большим количеством файлов ... но не так интенсивно, как в rsync.
ксенотеррацид
2

В этом примере файлы будут перемещены из «/ parent / old-dir» в «/ parent»:

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

По правилам rsync он заменит дупс более новыми файлами из old-dir.

Александр Погребняк
источник
1

Можешь попробовать

find . -maxdepth 1 -print0 | xargs -I '{}' -r0 mv '{}' ..

который перезапишет дубликаты в ..

Вы можете использовать mv -u '{}', чтобы не перезаписывать, если дублирование в .. такое же или более новое


источник
зачем трубу найти ксаргсу? почему бы не использовать +
ксенотеррацид
1
@xenoterracide - привычка и переносимость (это расширение GNU). Кроме того, я только что попробовал это и не могу понять, как передать второй параметр ..в mv '{}' +команду, поскольку + просто добавляет в конец.
@ Я знаю, что + находится в POSIX. Мне уже говорили, что GNU запоздало, чтобы получить его.
ксенотеррацид
Вы правы, но я все еще не могу
2
@xenoterracide: С GNU Coreutils: -exec mv -t .. -- {} +. Портабельно: -exec sh -c 'mv -- "$@"' _ {} +.
Жиль "ТАК ... перестать быть злым"
1

mv -i только подсказки, если пункт назначения существует.

yes n | mv -i …перемещает все файлы, которые не существуют в каталоге назначения. В FreeBSD и OSX вы можете сократить это до mv -n ….

Обратите внимание, что ни один из них не объединит аргумент каталога с существующим каталогом с тем же именем в каталоге назначения.


Отдельный вопрос - как действовать со всеми файлами в текущем каталоге. Есть две проблемы: захват всех файлов (без *точечных файлов) и не запуск в командной строке. В Linux (или в более общем случае с GNU find и GNU coreutils):

find . -mindepth 1 -maxdepth 1 -exec mv -i -t .. -- {} +

С помощью GNU найдите, но не GNU coreutils (или более старые GNU coreutils):

find . -mindepth 1 -maxdepth 1 -exec sh -c 'mv -i -- "$@" "$0"' .. {} +

Портабельно:

find . -name . -o -exec sh -c 'mv -i -- "$@" "$0"' .. {} -type d -prune

Как обычно, Zsh облегчает работу. Он не имеет внутреннего ограничения командной строки, поэтому, если вы используете его mvвстроенную функцию, вам не нужно об этом беспокоиться. И вы можете сказать ему не игнорировать точечные файлы с помощью Dквалификатора glob. Ограничение: это не работает в файловых системах (по состоянию на zsh 4.3.10).

zmodload zsh/files
mv -i -- *(D) ..
Жиль "ТАК - прекрати быть злым"
источник
много аргументов?
ксенотеррацид
0

Я сказал на нашем ML

mv * ..

очевидно, это не очень безопасно ... это перезапишет вещи. Это может иметь ограничения, с которыми я никогда не сталкивался.

xenoterracide
источник
2
Если у вас есть большое количество файлов, вы, скорее всего, получите «список аргументов слишком длинная ошибка».
2
Это может сделать плохо, если у вас есть имя файла, которое начинается с -. Он не будет ловить файлы, чье имя начинается с ..
Жиль "ТАК - перестань быть злым"
0

Ниже приведен шаблон Python, который я использовал для хорошего эффекта в прошлом.

#!/usr/bin/env python
#
# Bart Kastermans, www.bartk.nl
#
# rename of collection of files in a directory
import os
import shutil

# only work on files whose name starts with a D
files = [filename for filename in os.listdir ("/Users/kasterma/Music/Audio Hijack/") if filename[0] =="D"]

for filename in files:
    shutil.move (filename, filename [:23] + ".mp3")
kasterma
источник