Автор Тема: Shell скрипт за актуализация на папка  (Прочетена 3895 пъти)

Radev

  • Напреднали
  • *****
  • Публикации: 218
    • Профил
    • WWW
Искам да актуализирам файловете в една папка от друга, но не искам да се копират всички файлове от актуалната папка, а само тези, които вече си ги има.

За да стане по-ясно давам пример:
Папка 1: file (date 31.01.07); Папка 2: file (date 9.02.07), file2;
след cp -xxxx /Папка 2 /Папка 1
Папка 1: file (date 9.02.07); Папка 2: file (date 9.02.07), file2;

Благодаря на отзовалите се!
Активен

Човек и добре да живее... !

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Shell скрипт за актуализация на папка
« Отговор #1 -: Feb 09, 2007, 16:16 »
Така, както си задал въпроса ще рече, че файлът file ще се актуализира, но ако има файл file2 в Папка1, но няма файл file2 в Папка2, то file2 не трябва да бъде копиран в Папка2. А така както си дал примера ще рече, че файлът file ще се актуализира, но ако има файл file2 в Папка2, но го няма в Папка1, то file2 не трябва да бъде закачан (т.е. не трябва Папка2 да се изпразва преди копирането от Папка1). Изясни кой от двата варианта искаш и ще ти драсна един скрипт... Много пресилено е да се нарече скрипт, по-скоро ще е файл с команда, който ще се стартира от cron или ръчно, ама както и да е



Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

Hapkoc

  • Напреднали
  • *****
  • Публикации: 2117
    • Профил
Shell скрипт за актуализация на папка
« Отговор #2 -: Feb 09, 2007, 16:30 »
#! /bin/sh

for file in $(ls -1 --color=no $path_to_papka2); do
  cp -u $path_to_papka2/$file $path_to_papka1/$file
done

--------------

много набързо без никакви гаранции

edit: вероятно ще има проблем при интервали в имената на файловете...



Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Shell скрипт за актуализация на папка
« Отговор #3 -: Feb 09, 2007, 17:17 »
Та... по начина, по който си си задал въпроса, ето как ще изглежда скрипта

#! /bin/sh

path_to_papka1=/път/до/папка1
path_to_papka2=/път/до/папка2
for i in $( ls $path_to_papka2 ); do
    cp $path_to_papka1/$i $path_to_papka2
done

За начина, по който си показал примера:

#! /bin/sh

path_to_papka1=/път/до/папка1
path_to_papka2=/път/до/папка2
cp $path_to_papka1/* $path_to_papka2

Кажи все пак какво точно имаш предвид. Току виж се оказало, че искаш съвсем друго нещо



Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Shell скрипт за актуализация на папка
« Отговор #4 -: Feb 09, 2007, 17:57 »
Цитат (Hapkoc @ Фев. 09 2007,17:30)
[...]
for file in $(ls -1 --color=no $path_to_papka2); do
[...]


Не само, че няма нужда от ls, ами ако има имена на файлове с embedded new lines или други "патологични" characters, скриптът няма да работи.


Примерен код

for file in /your/path/*;do ...




Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Shell скрипт за актуализация на папка
« Отговор #5 -: Feb 09, 2007, 18:35 »
radoulov, забележката ти не е насочена точно към моя пост, но обхваща и него, затова ще попитам как аджеба ше стане според теб така? Ще дам пример със скрипта на Harkoc, защото е подобен и защото ти си използвал него. Когато зададеш
for file in /path/to/folder2/*;do ...
променливата file приема стойност /path/to/folder2/file и не виждам как да му кажеш да копира от Папка1 само файловете, които ги има в Папка2. В нашите скриптове променливата file (при мен i) приема стойност последователно всеки файл в Папка2, но стойността и е само името на файла, не и пътя до него и така можеш да правиш каквото си поискаш с променливата. Всъщност виждам как ще стане твоето. С cut да режеш части от променливата и да наслагваш... нужно ли е за едно такова елементарно действие?

P.S.: Иначе да, има проблем, когато в името на файла има интервал. Тогава променливата приема стойност за всяка дума поотделно



Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Shell скрипт за актуализация на папка
« Отговор #6 -: Feb 09, 2007, 18:52 »
Цитат

radoulov, забележката ти не е насочена точно към моя пост, но обхваща и него, затова ще попитам как аджеба ше стане според теб така? Ще дам пример със скрипта на Harkoc, защото е подобен и защото ти си използвал него. Когато зададеш
for file in /path/to/folder2/*;do ...
променливата file приема стойност /path/to/folder2/file и не виждам как да му кажеш да копира от Папка1 само файловете, които ги има в Папка2.
В нашите скриптове променливата file (при мен i) приема стойност последователно всеки файл в Папка2, но стойността и е само името на файла, не и пътя до него и така можеш да правиш каквото си поискаш с променливата. Всъщност виждам как ще стане твоето. С cut да режеш части от променливата и да наслагваш... нужно ли е за едно такова елементарно действие?


Без външни команди (ls) и subshells($()):

Примерен код

$ mkdir dir1 dir2

$ touch dir1/file1 dir1/file2 dir2/file1

$ for i in dir2/*;do
> echo "cp -u dir1/"${i##*/}" dir2" # echoing for demonstration
> done
cp -u dir1/file1 dir2




Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Shell скрипт за актуализация на папка
« Отговор #7 -: Feb 09, 2007, 19:25 »
Всъщност аз бих го написал така:

Примерен код

cd dir1
set -- ../dir2/*
cp -u "${@##*/}" ../dir2
Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Shell скрипт за актуализация на папка
« Отговор #8 -: Feb 10, 2007, 06:04 »
radoulov, извинявай, че пак ще ти противореча, но... ти изпробваш ли скриптовете, преди да ги дадеш тук?
Относно скрипта
cd dir1
set -- ../dir2/*
cp -u "${@##*/}" ../dir2
той запомня само последната променлива и по този начин копира само последния файл, тъй като нямаш цикъл. Да не говорим, че е противопоказно в скриптове да се използват относителни пътища.
За скрипта
$ for i in dir2/*;do
> echo "cp -u dir1/"${i##*/}" dir2" # echoing for demonstration
> done
cp -u dir1/file1 dir2
Първо, копирането е извън цикъла, друг въпрос и че първо използваш променлива i, после незададена променлива file1 (считаме, че е променлива, макар че не си сложил $ пред нея)... демек пак не става така. Второ, нали ти казах, че така зададена променливата i приема стойност пълния път до файла и така, като изпълниш командата cp -u $dir1/$i $dir2, скрипта ще търси файл за копиране в папка $dir1/$dir2, която не съществува. От начина, по който даваш примери, заключавам че или си някой велик гуру, който не схваща че не му четем мислите (защото аз не мога да разбера как се изпълняват скриптовете ти) или си пишеш из форума ей така за спорта, което вреди на правилната информация. Когато даваш за пример някакъв скрипт (особено такъв елементарен като този), нищо не ти пречи първо да го пробваш, за да видиш дали нещата сработват и след това да го даваш тук  ':xclam:'

edit: Hapkoc, въпреки че съм чел достатъчно твои постове и те уважавам, ще ти напомня и на теб, че не всеки знае, че дадена променлива трябва първо да бъде зададена, преди да се използва. Много хора биха се чудили защо не сработва скрипта ти, а то ще е защото не са задали стойност на $path_to_papka1 и на $path_to_papka2



Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

Hapkoc

  • Напреднали
  • *****
  • Публикации: 2117
    • Профил
Shell скрипт за актуализация на папка
« Отговор #9 -: Feb 10, 2007, 10:41 »
Цитат
edit: Hapkoc, въпреки че съм чел достатъчно твои постове и те уважавам, ще ти напомня и на теб, че не всеки знае, че дадена променлива трябва първо да бъде зададена, преди да се използва. Много хора биха се чудили защо не сработва скрипта ти, а то ще е защото не са задали стойност на $path_to_papka1 и на $path_to_papka2


прав си :)
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Shell скрипт за актуализация на папка
« Отговор #10 -: Feb 10, 2007, 12:28 »
Цитат
radoulov, извинявай, че пак ще ти противореча, но... ти изпробваш ли скриптовете, преди да ги дадеш тук?
Относно скрипта
cd dir1
set -- ../dir2/*
cp -u "${@##*/}" ../dir2
той запомня само последната променлива и по този начин копира само последния файл, тъй като нямаш цикъл. Да не говорим, че е противопоказно в скриптове да се използват относителни пътища.



Изключително интересно мнение ...  
Така, имаме две папки:

dir1 -> file1, file2, file3
dir2 -> file1, file3

Искаме да актуализираме само file1 и file3, копирайки новите версии от dir1 в dir2,
Скриптът ще бъде с "echo", за да се вижда, какво точно се копира:

Примерен код

$ cd dir1
$ set -- ../dir2/*
$ echo "cp -u "${@##*/}" ../dir2"
cp -u file1 file3 ../dir2
 

На теб какво ти дава, че се копира само file3 (казваш само последния ...)?
Относно относителните пътища: не бих искал сега да се отклонявам от темата,
но ако предпочиташ, можеш да замениш dir1 и dir2 с absolute path, променлива и т.н,
с този скрипт само илюстрирам похват.  

Цитат

За скрипта
$ for i in dir2/*;do
> echo "cp -u dir1/"${i##*/}" dir2" # echoing for demonstration
> done
cp -u dir1/file1 dir2
Първо, копирането е извън цикъла, друг въпрос и че първо използваш променлива i, после незададена променлива file1 (считаме, че е променлива, макар че не си сложил $ пред нея)... демек пак не става така. Второ, нали ти казах, че така зададена променливата i приема стойност пълния път до файла и така, като изпълниш командата cp -u $dir1/$i $dir2, скрипта ще търси файл за копиране в папка $dir1/$dir2, която не съществува. От начина, по който даваш примери, заключавам че или си някой велик гуру, който не схваща че не му четем мислите (защото аз не мога да разбера как се изпълняват скриптовете ти) или си пишеш из форума ей така за спорта, което вреди на правилната информация. Когато даваш за пример някакъв скрипт (особено такъв елементарен като този), нищо не ти пречи първо да го пробваш, за да видиш дали нещата сработват и след това да го даваш тук  


Прочетох това 3 пъти, докато разбера какво имаш предвид
(и все още не съм абсолютно сигурен, дали съм разбрал).
Разковничето, може би, е в тези думи: "... после незададена променлива file1 ...".
Очевидно, не си разбрал (сложих даже коментар), че там, където виждаш file1,
е изходът (the output) от цикъла, т.е. това, което ще се извърши, като премахнеш командата echo.
Ако все още не е ясно, това което съм написал,
сам съгласен с теб, че определено съм сбъркал форума '<img'>


P.S. Извинявам се за многократното редактиране, но ми е изключително трудно да пиша на кирилица.



Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Shell скрипт за актуализация на папка
« Отговор #11 -: Feb 10, 2007, 18:18 »
Първото, което ще кажа сега е, че тази тема е в секция "Общ форум". Това ще рече, че биха я чели и много начинаещи. За целта в тази секция трябва дори и най-сложните неща да се обяснят достатъчно подробно и ясно, за да може на начинаещия да му стане ясно. Иди обяснявай на първокласници диференциални уравнения по начина, по който се предават във ВУЗ-овете и да видим ще схванат ли нещо  '<img'>

Цитат
Искаме да актуализираме само file1 и file3, копирайки новите версии от dir1 в dir2


Цитат
cp -u file1 file3 ../dir2


Човека от де ще знае кои файлове трябва да се копират? Нали скрипта ще работи самостоятелно, няма след всяка промяна на съдържанието на папките да редактира скрипта я. Ето защо трябва цикъл. Той ще проверява кои файлове трябва да се копират и ще извърши действието.

По ей този случай ще дръпна още едно обяснение, пък дано схванеш
for i in dir2/*;do
cp -u dir1/"${i##*/}" dir2
Ако dir2 = /home/user/papka2, a dir1 = /home/user/papka1, то при изпълнението на командата cp -u dir1/"${i##*/}" dir2, скрипта ще изпълни команда
cp -u /home/user/papka1//home/user/papka2/file /home/user/papka2
Както се сещаш, папка /home/user/papka1//home/user/papka2 не съществува. Няма повече да се занимавам с тази тема
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

Radev

  • Напреднали
  • *****
  • Публикации: 218
    • Профил
    • WWW
Shell скрипт за актуализация на папка
« Отговор #12 -: Feb 11, 2007, 12:59 »
Благодаря на всички, ще опитам и ще кажа какво се е случило!
Активен

Човек и добре да живее... !

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Shell скрипт за актуализация на папка
« Отговор #13 -: Feb 11, 2007, 13:51 »
Цитат
По ей този случай ще дръпна още едно обяснение, пък дано схванеш
for i in dir2/*;do
cp -u dir1/"${i##*/}" dir2
Ако dir2 = /home/user/papka2, a dir1 = /home/user/papka1, то при изпълнението на командата cp -u dir1/"${i##*/}" dir2, скрипта ще изпълни команда
cp -u /home/user/papka1//home/user/papka2/file /home/user/papka2
Както се сещаш, папка /home/user/papka1//home/user/papka2 не съществува. Няма повече да се занимавам с тази тема



Че моят пост е неуместен тук: съмнение вече няма.  
Това, с което не мога да се примиря, е тази нелепа неграмотност и арогантност.
За тези, които искат да научат базите на shell scripting,
показвам:

positional parameters and variable expansion

Примерен код

$ ls -l dir2
total 0
-rw-r--r-- 1 Administrator None 0 Feb  9 18:23 file1
-rw-r--r-- 1 Administrator None 0 Feb  9 18:23 file2

$ set -- dir2/*

$ echo "${@}"
dir2/file1 dir2/file2

$  echo "${@##*/}"
file1 file2

$ for i; do # "for i" bez argumenti, tryabva li da obyasnyavam i tova :)?
>  echo "[izhod] Tova, koeto neter ne moje da razbere, novoto ime shte e: ${i##*/}"
>  echo "[izhod] A komandata copy shte bude: cp -u dir1/${i##*/} dir2"
> done
[izhod] Tova, koeto neter ne moje da razbere, novoto ime shte e: file1
[izhod] A komandata copy shte bude: cp -u dir1/file1 dir2
[izhod] Tova, koeto neter ne moje da razbere, novoto ime shte e: file2
[izhod] A komandata copy shte bude: cp -u dir1/file2 dir2



Няма да обяснявам и защо е по-ефикасно без for loop (изглежда, че ще е твърде advanced:)).

Поздрави,
Димитър

P.S. Моят пост беше насочен към тези, които бяха отговорили, не към Radev, за него, преполагам, ще е по-лесно да разбере неефикасните решения.



Активен


Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
Безплатен Shell Акаунт
Настройка на програми
madmad 2 2450 Последна публикация Jun 28, 2010, 18:03
от betso
Gnome SHELL
Настройка на програми
pi6in 0 1681 Последна публикация Dec 29, 2010, 17:21
от pi6in
GNOME-Shell смяна на темата на иконите
Настройка на програми
alkor 4 2686 Последна публикация Jun 22, 2011, 09:36
от radoshow
shell скрипт
Общ форум
AMD 15 5103 Последна публикация Dec 29, 2011, 23:27
от AMD
Bourn shell скрипт
Общ форум
h4rd2kill 31 9896 Последна публикация Jun 21, 2012, 13:00
от radoulov