LINUX.ORG.RU
решено ФорумAdmin

Перенос файлов с присвоением новых прав.

 ,


0

1

Всем привет. Вот встала такая задача:
как переместить файлы/папки из одной папки в другую, присвоить копируемым файлам/папкам нужные права, и при совпадении имен переименовать копируемый файл/папку скажем в такой формат - xxx(2)
Пока имею следующий текст:

#!/bin/bash
cd /incoming
chmod -R 505 /incoming
mv /incoming/* /1/Man
find /incoming/ -type d -exec chmod 777 {} \;
chmod -R 505 /1/Man/
1) Папка Man и все содержимое должно быть только для чтения.
2) Папка incoming должна быть доступна для чтения и записи.
3) Как сделать переименование при совпадении имен?

3) Как сделать переименование при совпадении имен?

man mv
...
       -b, --backup
              Делать резервные копии файлов, которые будут перезаписаны или удалены.

Не?

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

Работает но криво, мне не бэкап нужно делать, а автопереименование при совпадении имён, юзер впадет в панику если его любимый файл вдруг станет с расширением ~ и не читаемый.

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

юзер впадет в панику

Всё. Приплыли. Юзер всегда впадёт в панику, что бы ты ни делал. Подстраиваешься под юзера - скоро сам впадёшь в панику.

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

Да нет же, я для краски написал так) Но в целом бьюсь уже несколько часов. Понимаю что должно быть еще в коде что-то такое:

j=0;
for i in *.*;
do let j+=1;
mv $i *$j ;
done
Но как его вкрутить в find?

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

Понимаю что должно быть еще в коде что-то такое:

Логика у тебя не та. Сначала сделай перенос файлов простыми и понятными средствами, а после уже приводи их к виду, который сочтёшь нужным. Пытаешься совместить два действия - получаешь кашу.

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

а после уже приводи их к виду, который сочтёшь нужным

Подсказываю постобработку:

find /1/Man -type f -name *~ -exec rename -v "s/\./,/;s/\./-$(date +%Y%m%d%H%M%S)./;s/\,/./;s/\~$//" {} \;
Deleted ()

Скрипт для перемещения файлов без замены (при совпадении имён старый файл остаётся, а новый называется «имя (число)».

#!/bin/bash
# Move files to dir, do not overwite existing but rename new file.
# USAGE:
# mv_noreplace.sh <file1> <file 2> .... <dest dir>
# results:
# dest dir/file 1
# dest dir/file 1 (2)
# dest dir/file 1 (3)
# EXAMPLE: 
# mv_noreplace.sh sourcedir/* "dest dir/"


set -euo pipefail
[ $# -ge 2 ] || { echo "Must specify the destination directory" >&2; exit 1; }
TARGETDIR=${*: -1}
[ -d "$TARGETDIR" ] || { echo "Destination must be a directory" >&2; exit 1; }

while [ $# -ge 2 ]; do
	IFNAME=$1; shift
	N=1
	NAME=`basename "$IFNAME"`
	RESNAME=$NAME
	while [ -e "$TARGETDIR/$RESNAME" ]; do
		N=`expr $N + 1`
		RESNAME="$NAME ($N)"
	done
	mv "$IFNAME" "$TARGETDIR/$RESNAME"
done
legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от Deleted

Не могу я так делать. В копируемой папке уже могут находится файлы с идентичным именем. И в таком случае при копировании буде замена, и переименовать будет уже не нужно(нечего).

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

В ней могут находиться файлы с текущей датой до секунды? Или о чём речь?

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

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

то мне кажется действие первое тупо исполнит с заменой файла если будет совпадение.

Для танкистов:

man mv
...
ОПЦИИ РЕЗЕРВНОГО КОПИРОВАНИЯ GNU
       GNU-версии таких программ как cp, mv, ln, install и patch могут, если потребуется, делать резервные копии файлов, которые будут перезаписаны,  изменены  или
       уничтожены.   При  желании,  резервные  копии  файлов  создаются  с  помощью опции -b.  Как они будут называться, задает опция -V.  В случае, если имя файла
       резервной копии создается с помощью добавления суффикса к имени исходного файла, то суффикс указывается с помощью опции -S.

       -b, --backup
              Делать резервные копии файлов, которые будут перезаписаны или удалены.

       -S СУФФИКС, --suffix=СУФФИКС
              Добавить СУФФИКС к имени файла при создании его резервной копии.

              Если данная опция не задана, то суффикс можно также задать,  используя  переменную  окружения  SIMPLE_BACKUP_SUFFIX  Если  не  задана  ни  опция,  ни
              переменная, то по умолчанию используется суффикс ~.

       -V МЕТОД, --version-control=МЕТОД
              Определяет,  как  будут  называться резервные копии файлов. Аргумент МЕТОД может принимать значения numbered (или t), existing (или nil) и never (или
              simple). Если данная опция не задана, то будет использовано значение переменной окружения  VERSION_CONTROL.   Если  же  не  задано  значение  и  этой
              переменной, то по умолчанию тип резервного копирования устанавливается в existing.

              Данная опция соответствует переменной version-control в Emacs.  Допустимыми значениями МЕТОД являются (допускаются однозначные сокращения):

              t, numbered
                     Всегда делать нумерованные резервные копии файлов.

              nil, existing
                     Делать нумерованные резервные копии файлов для файлов, которые уже их имеют и простые резервные копии для остальных файлов.

              never, simple
                     Всегда делать простые резервные копии.

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

Итак дело сдвинулось немного.
запуская команду:
mv --backup=t /incoming/* /1/Man
я получаю желаемый результат, НО!
к примеру я копирую файл 1.txt, который уже есть в каталоге. после выполнения команды, появляется файл 1.txt.~1~((( Как сделать чтобы он не трогал расширение файла?
С suffix тоже не получается(, добавляет в расширение а не в имя(
Я совсем что-то отупел(

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

Надо понимать что 1.txt.~1~ - это СТАРЫЙ файл, который был переименован чтобы на него место можно было положить 1.txt из источника.

Ещё надо понимать, что в юниксах нет понятия «расширения имени файла» и стандартные утилиты о нём не знают.

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

Подсказываю постобработку:

Хмм. Забыл. Для непосредственно указанного пути не нужно экранирование начальной точки:

find /1/Man -type f -name *~ -exec rename -v "s/\./-$(date +%Y%m%d%H%M%S)./;s/\~$//" {} \;
Deleted ()
Ответ на: комментарий от legolegs

Ещё надо понимать, что в юниксах нет понятия «расширения имени файла» и стандартные утилиты о нём не знают.

И как тогда быть? Как ему сказать чтобы не трогал ничего все что после последней точки в названии файла?

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

Хмм. Забыл. Для непосредственно указанного пути не нужно экранирование начальной точки:

Может я что-то не понимаю, но как получится не удалить файл с одинаковым именем, если сначала происходит процедура перемещения, а только потом переименования?

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

Итак, что у меня получилось:

#!/bin/bash

cd /1/incoming
mv -b /1/incoming/* /1/Man/
find /1/Man/ -type d -name *~ -exec rename -v "s/\~$/-$(date +%Y-%m-%d_%H%M%S)/" {} \;
find /1/Man/ -type f -name *~ -exec rename -v "s/\./-$(date +%Y-%m-%d_%H%M%S)./;s/\~$//" {} \;
chmod -R 505 /1/Man/
При таком скрипте файлы и папки помещенные в директорию «incoming» переместятся в директорию «Man» с применением прав 505.
Думаю этого более чем достаточно в моем случае.
Всем огромное спасибо за помощь и советы, выручили, помогли)

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

этого более чем достаточно

Перебор.

Первый rename заменит file.txt~ на file.txt-{YYYY-MM-DD-HHMMSS}, а второй вообще не при делах.

Может их местами переставить. Если второй не смог переименовать file.txt~ в file-{YYYY-MM-DD-HHMMSS}.txt, то первый переименует в file.txt-{YYYY-MM-DD-HHMMSS}.

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

Перебор.
Первый rename заменит file.txt~ на file.txt-{YYYY-MM-DD-HHMMSS}, а второй вообще не при делах.
Может их местами переставить. Если второй не смог переименовать >file.txt~ в file-{YYYY-MM-DD-HHMMSS}.txt, то первый переименует в >file.txt-{YYYY-MM-DD-HHMMSS}.

Первый работает с папками, второй с файлами, я все проверил, все работает.)

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

я все проверил, все работает

Твою мать, сорян, это я в глаза долблюсь. Удачи.

PS: И всё-таки предусмотри третий rename на случай, если в имени файла нет точки.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)