Jak bezpiecznie przenosić pliki w górę o jeden katalog?

10

Jak mogę przenieść pliki do katalogu, w którym mogą znajdować się setki lub tysiące plików, a Ty możesz nie być pewien, czy są w nim duplikaty ... Jakiej metody byś użył?

Sposób obsługi duplikatów będzie się różnił, czasem nadpisujemy, czasem musimy być bezpieczniejsi. IO może być ważne, ponieważ są to serwery produkcyjne. Ale biorąc pod uwagę ilość monitów o niepubliczne pliki, nie jest opcją. Ważne jest zachowanie uprawnień, znaczników czasu itp. Zwykle nie wiemy, jakie są dane.

No i korzystanie z niego mvnie jest wymagane rsync, cprozwiązania mile widziane.

Uwaga: korzystamy z CentOS 5.5, więc daj mi znać, jeśli to nie zadziała, ponieważ jest to nowsza ... funkcja

ksenoterracid
źródło
Co chcesz zrobić z duplikatami?
@Iain zależy od sytuacji? Pracuję na serwerze internetowym ... to naprawdę zależy od tego, mvczy zależy nam na zachowaniu w przypadku ... i czy już zrobiliśmy kopię zapasową. To pytanie jest dość otwarte. Po prostu szukam dobrych opcji, a może komentarza na temat tego, czy może cię ugryźć i jak.
ksenoterrakid,
Zakładam, że jest zbyt wiele plików, aby powłoka mogła obsłużyć mv * ../lub mv -i * ../?
Michael Mrozek
@Michael jestem pewien, że jest różny ... w niektórych przypadkach prawdopodobnie nie. W niektórych przypadkach może. Próbuję wyłapać jak najwięcej opcji w mojej środowisku pracy.
ksenoterrakid,

Odpowiedzi:

6

Polecam użycie rsync od rodzica:

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

który utworzy kopię zapasową wszystkich istniejących duplikatów plików nadrzędnych do oryginalnych plików .

Tok
źródło
Myślę, że -aimplikuje-r
ksenoterracid
@xenoterracide - Right you 'r'
Tok
@Tok czy można zrobić kopię jako hardlink? aby nie marnować IO. (jak -ldla cp)
ksenoterracid
@xenoterracide - Możesz użyć flagi -Hlub --hard-linksdla rsync, aby zachować twarde linki.
Tok
1
@xenoterracide - Możesz użyć --link-dest=DIRflagi, aby osiągnąć to zachowanie jako: rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/która będzie dowiązać do dst / dowolnych niezmienionych plików między src i src, w tym przypadku wszystkich plików. Zwykle ta flaga jest używana, gdy chcesz ponownie połączyć pliki kopii zapasowych bez kopiowania ich danych, takich jak --link-dest=/most/recent/backup.
Tok
4
cp -bal . ..

Spowoduje to skopiowanie wszystkiego z bieżącego katalogu do katalogu nad nim, zachowując wszystkie uprawnienia, używając dowiązań twardych, aby zminimalizować IO, jeśli to możliwe, a na duplikatach tworzy nazwę pliku ~

po tym

rm -rf . ; cd .. ; rmdir <originaldir>;
ksenoterracid
źródło
prawdopodobnie występuje problem z dużą liczbą plików ... ale nie jest tak intensywny jak we / w rsync.
ksenoterrakid,
2

W tym przykładzie pliki zostaną przeniesione z „/ parent / old-dir” do „/ parent”:

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

Według reguł rsync zastąpi dups nowszymi plikami z old-dir.

Alexander Pogrebnyak
źródło
1

Możesz spróbować

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

co spowoduje zastąpienie duplikatów w…

Możesz użyć mv -u '{}', aby nie zastępować, jeśli dupe w .. jest taki sam lub nowszy


źródło
dlaczego znaleźć rurkę do xargs? dlaczego nie zastosować +
ksenoterrakidu
1
@xenoterracide - Zwyczaj i przenośność (jest to rozszerzenie GNU). Co więcej, właśnie go wypróbowałem i nie mogę dowiedzieć się, jak przekazać drugi parametr ..do mv '{}' +polecenia, ponieważ + dodaje tylko do końca.
@Iain + jest w POSIX- ie, powiedziano mi wcześniej, że GNU find jest za późno, aby go zdobyć.
ksenoterracid,
Masz rację, ale nadal nie mogę znaleźć sposobu na użycie ...
2
@xenoterracide: Z coreutils GNU: -exec mv -t .. -- {} +. Przenośnie: -exec sh -c 'mv -- "$@"' _ {} +.
Gilles „SO- przestań być zły”
1

mv -i pyta tylko, czy miejsce docelowe istnieje.

yes n | mv -i …przenosi wszystkie pliki, które nie istnieją w katalogu docelowym. W FreeBSD i OSX możesz to skrócić mv -n ….

Zauważ, że żaden z nich nie połączy argumentu katalogu z istniejącym katalogiem o tej samej nazwie w katalogu docelowym.


Osobnym problemem jest sposób działania na wszystkie pliki w bieżącym katalogu. Istnieją dwa problemy: pobieranie wszystkich plików ( *pomija pliki kropkowe) i nie uruchamianie się w wierszu poleceń. W systemie Linux (lub bardziej ogólnie z GNU find i coreutils GNU):

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

Z GNU znajdź, ale nie jądra GNU (lub starsze jądra GNU):

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

Przenośny:

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

Jak zwykle zsh ułatwia. Nie ma wewnętrznego ograniczenia długości wiersza poleceń, więc jeśli używasz jego mvwbudowanego programu, nie musisz się tym martwić. Możesz powiedzieć, aby nie ignorować plików kropek za pomocą Dkwalifikatora glob. Ograniczenie: to nie działa w różnych systemach plików (od zsh 4.3.10).

zmodload zsh/files
mv -i -- *(D) ..
Gilles „SO- przestań być zły”
źródło
na wiele argumentów?
ksenoterrakid,
0

Powiedziałem o naszym ML

mv * ..

oczywiście nie jest to zbyt bezpieczne ... nadpisze rzeczy. Może mieć ograniczenia, których nigdy nie spotkałem.

ksenoterracid
źródło
2
Jeśli masz dużą liczbę plików, prawdopodobnie pojawi się „błąd zbyt długiej listy argumentów”.
2
Może mieć złe rzeczy, jeśli nazwa pliku zaczyna się od -. Nie złapie plików, których nazwa zaczyna się od ..
Gilles „SO- przestań być zły”
0

Poniżej znajduje się szablon Pythona, z którego korzystałem w przeszłości.

#!/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
źródło