LINUX.ORG.RU
ФорумAdmin

Копирование с определенной структурой


0

0

Суть такова.
Есть определенный список папок и фалов в них. Файлов очень много.
Назовем этот список структурой.
Мне нужно сделать скрипт который бы мог создать такую же структуру, и скопировать все файлы в нее из любого места.
То есть предположем есть каталог

/cool
   /cool/1
   /cool/2
   .....
   /cool/file1
   /cool/file2
   .....
   /cool/fileN
Вот пример структуры.
Теперь предположем есть Каталог /dist в котором есть все файлы что в каталоге /cool только лежат ну например в корне или вообще в любом другом порядке отличным от порядка каталога /cool.

Скрипт из каталога /dist должен скопировать все файлы так чтобы они лежали в такой же структуре как и в каталоге /cool.
Наверное я вас запутал )))


Я не силен в таком деле, но пока вот что придумал.
С помощью команды find /cool создаем весь список файлов.

find /cool > ./list
Затем считываем Имя файла из list, и ищем его в /dist . После копируем его туда где он находился поменяв в пути /cool на свой каталог.

demsi ()
find /cool -type f -print0 | while read -d $'\0' -r path
do
dirname=«/dist$(dirname »${path#/cool}")"
mkdir -p «$dirname»
find /dist -type f -name «$(basename »$path")" -exec mv {} «$dirname» \;
done



Не проверял. Содержит bashизмы.

AITap ★★★★★ ()

где-то так :

foreach name [ split [ exec find -type f /dist ] "\n" ] {
  set tail [ file tail $name ]
  set dist($tail) $name
}
foreach name [ split [ read [ open $coolFile "r" ] ] "\n" ] {
  set tail [ file tail $name ]
  if [ info exist dist($tail) ] {
     file copy -force -- $dist($tail) $cool($tail)
  }
}

в принципе можно на любом языке, но сегодня уже давал ответы с tcl, так что пусть булет tcl.

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

Сейчас сам проверю )))
По сути если например /cool удалить перед тем как записать

find -type f /cool > list
Потом вместо строчки
find /cool -type f -print0 | 
можно будет писать ?
cat ./list | 

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

в принципе можно на любом языке, но сегодня уже давал ответы с tcl, так что пусть булет tcl.

Меня обычный bash устраивает для этих целей.

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

-print0 печатает пути к файлам, разделённые нулевыми байтами (\0 - единственный символ, которого не может быть в пути к файлу в UNIX-подобных системах). read -d $'\0' читает этот список, разделяя нулевым байтом. Соответственно, find -type f /cool тоже нужно запускать с -print0.

AITap ★★★★★ ()
tar -cf - -C /dist cool | tar -xf - -C /some/other/path

Каталог cool со всеми подкаталогами будет скопирован из /dist в /some/other/path

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

-print0 печатает пути к файлам, разделённые нулевыми байтами (\0 - единственный символ, которого не может быть в пути к файлу в UNIX-подобных системах). read -d $'\0' читает этот список, разделяя нулевым байтом. Соответственно, find -type f /cool тоже нужно запускать с -print0.

Чисто из интереса, если сделать
find -type f /cool > list
а потом поменять \0 на \n
while read -d $'\n' -r path
Как я знаю из с++ \n это перенос строки. Получается bash распознает все спец.символы ?
Я просто для интереса спросил, эта затея глупа так как символ \n может быть частью имени файла.
А как создавать файлы с такими именами ?
touch ./new\nfile или touch ./new'\n'file

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

в вышепредложенном bash скрипте - вложенный цикл и find на каждую строку из списка cool; Это неспортивно :)

надо отдельно выносить чтение cool (или dist - на вкус и цвет) в ассоциативный массив. Тогда будет комильфо.

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