Skopiuj zawartość katalogu za pomocą polecenia „cp”


33

Jak skopiować całą zawartość jednego katalogu do innego?

Na przykład:

$ cd /home/newuser
$ cp -a /backup/olduser/* .

Problem z powyższym polega na tym, że wzór globowania „*” pasuje do ukrytych katalogów ”. i „..”, a skończysz na katalogu „olduser” wewnątrz „newuser”, a także na zawartości.

Możesz także zrobić coś takiego:

$ rmdir /home/newuser
$ cp -a /backup/olduser /home/newuser

Ale co jeśli newuser zawiera już jakieś domyślne pliki i katalogi?

Jaki jest najprostszy, najbardziej poprawny, najłatwiejszy do zapamiętania, a nie nieporządny sposób przenoszenia zawartości jednego katalogu do drugiego za pomocą prostej komendy „cp” i powłoki?

Odpowiedzi:


30

Próbować:

cp -ra /backup/olduser/. /home/newuser

To wspaniale, ale nie mogę dokładnie zrozumieć, jak to działa. Myślę, że to prawdopodobnie dlatego, że nie rozumiem, jak .i jak ..działa. Chcesz to wyjaśnić?
— bradley.ayers

To działało dla mnie, ale cp -r ./a bnie. Masz pomysł, dlaczego?
— Bryg.

2
też działa dla mnie, ale ropcja nie jest potrzebna. aOpcja zakłada r.
— MountainX

1
parametr -r wydaje się w tym momencie nieco redundantny!
— Master of Celebration

23

Dwa katalogi a i b.

Oba mają pliki.

Jesteś w katalogu, który zawiera aib.

cp -r ./a b

-r = rekurencyjnie.


Czy nie chcesz -a, aby uzyskać wszystkie pliki?
— mc

7
Argument -a nie ma nic wspólnego ze wszystkimi plikami, jest skrótem od archiwizacji, zachowa własność pliku, uprawnienia, czasy dostępu itp. Argument -a (choć bardzo przydatny) nie jest standardową opcją, a kilka implementacji cp nie zapewniam tego.
— theotherreceive

1
@mch: automatycznie dołączany, ponieważ kazałeś cpskopiować katalog ai a/.somedotfilejest on zawarty przez a. jeśli bistnieje, to polecenie utworzy dokładną kopię pliku aat b/a.
— quack quixote

2
Łatwy sposób:cp -R /some/dir/* /another/dir
— n0pe

1
To kopiuje a / foo do b / a / foo zamiast do b / foo
— Sparr

18

Pamiętaj też, że domyślnie cp kopiuje pierwszy katalog do drugiego katalogu, jeśli drugi istnieje. Na przykład cp -a a bskopiuje INTO b, jeśli istnieje b, tzn. Utworzy a do b.

Jeśli nie jest to, czego chcesz i chcesz skopiować zawartość a do b (na przykład podczas kopiowania całego systemu plików do punktu montowania) użyj:

cp -a a/. b

jak w poprzedniej odpowiedzi.

Należy również pamiętać, że -aobejmuje -rto -arjest zbędne.


Jak /.działa
— bradley.ayers

a/.reprezentuje zawartość katalogu „a” w przeciwieństwie do samego katalogu, w większości przypadków jest synonimem, ale podczas używania cp -runika domyślnego zachowania cp (kopiowanie INTO b).
— Nicolas Bonnefon,

świetna wskazówka, właśnie tego szukałem, ale nie udało mi się znaleźć gdzie indziej - wszystkie te „foo / *” lub „-r foo /”, które zawodzą w narożnych przypadkach.
— Tener

@TimoHuovinen '. ” wcale nie jest symbolem wieloznacznym. Jest to dosłownie katalog „nadrzędny”, a „..” to dziadek. Oznacza to „/foo/./././././.” to ten sam katalog co „/ foo”, a „/ foo / bar / ..” to ten sam katalog co „/ foo”. Pomyśl o nich jak o dowiązaniach twardych wbudowanych w system plików.
— quuxman

@quuxman dziękuję, wtedy nie byłem tego świadomy. Usunę mój stary komentarz, aby uniknąć mylących ludzi.
— Timo Huovinen,

6

O ile poważnie nie zmieniłeś konfiguracji powłoki, wzór globowania „*” nie pasuje ”. lub „..”, ponieważ można to zweryfikować za pomocą echa *. Zamiast tego pomija pliki, których nazwa zaczyna się od „.”, Więc twoje podejście pominie wszystkie ukryte pliki. Możesz poprawić niektóre z tych zachowań za pomocą opcji powłoki, na przykład opcji dotglob w bash, ale wtedy nie będzie to przenośna i niezawodna opcja, której szukasz.

Jeśli musisz to zrobić więcej niż raz lub dwa razy, radzę zajrzeć do rsync lub unison (w zależności od konkretnych potrzeb) ze starannie spreparowanymi specyfikacjami źródłowymi i docelowymi.

Inną alternatywą jest umieszczenie katalogu źródłowego w archiwum tar i rozpakowanie go nad istniejącym katalogiem docelowym.


1
używam tego: ( cd /src/dir ; tar cf - . ) | ( cd /dest/dir ; tar xf - )... tar cf - .tar jest katalogiem źródłowym, zawiera pliki dotfiles i wypluwa go do STDOUT, który jest przesyłany do STDIN pliku tar xf -.
— quack quixote

Myślę, że sednem PO jest to, jak odwoływać się do plików zaczynających się od „.” ale nie specjalne ”. i katalogi „..”. Jest o wiele bardziej eleganckie rozwiązanie powyżej zamiast używania rsync lub innego złożonego programu.
— quuxman

2

Spowoduje to skopiowanie zarówno normalnych, jak i ukrytych plików, z wyłączeniem katalogu nadrzędnego ( ..):

cd /directory/to/copy
cp -r * .[^.]* /destination/directory

Jeśli nie wykluczysz katalogu nadrzędnego, skończysz z całą zawartością ..katalogu docelowego.


1
Ale nadal wyklucza to nazwy rozpoczynające się od .. (np. ...Lub ..super-hidden).
— Scott

0

Aby skopiować pliki zaczynające się od kropki, po prostu wykonaj cp. * Target /

Najłatwiej jest po prostu wykonać polecenie cp dwa razy.

Jak mówi Peter Eisentraut, normalne zasady globowania nie obejmują… i. (hm, jak zakończyć to zdanie?;)

Wystarczy użyć -r, aby uczynić go rekurencyjnym, i -i, aby polecenie cp zapytało, czy naprawdę chcesz zastąpić plik.

cp -ri /backup/olduser/* /newuser/
cp -ri /backup/olduser/.* /newuser/

Zwykle *nie pasuje .lub .., ale tak jest, jeśli używasz .*. Spróbować echo .*. Można wykluczyć .i ..z następującym wzorem: .[^.]*.
— mch

@mch: Ale .[^.]*nadal wyklucza nazwy rozpoczynające się od .. (np. ...lub ..super-hidden).
— Scott

0

Działa to w przypadku kopiowania wszystkich plików i katalogów z wyjątkiem ukrytych katalogów rekurencyjnie z bieżącego katalogu do dowolnego miejsca:

cp -rf * ^.* 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.