Jak skopiować ukryte (zaczynające się od kropki) pliki i podkatalogi w systemie Linux?


10

Jak skopiować ukryte pliki i ukryte podkatalogi (te zaczynające się od kropki) z folderu A do folderu B? Na przykład, jeśli mam tę strukturę:

A/a
A/b
A/.a
A/.b/
A/.b/somefile
A/.b/.c

Chciałbym skopiować do B tylko ukryte pliki i ukryte podkatalogi w A:

B/.a
B/.b/
B/.b/somefile
B/.b/.c

Próbowałem już tego polecenia: cp A/.* Bz tego innego pytania superużytkownika . Jednak nie kopiuje podkatalogów. Próbowałem też cp -r A/.* B, ale kopiuje, .więc kończę dokładną kopią A (w tym normalnych plików). Każda pomoc jest mile widziana.

Odpowiedzi:


16

Tak długo, jak szukasz ukrytych plików i folderów na poziomie A i na przykład nie chcesz

A/b/.hidden

do skopiowania, powinieneś móc użyć tego:

cp -r A/.[^.]* B

Zasadniczo oznacza to skopiowanie wszystkiego, co zaczyna się od a, .a następnie dowolnego znaku innego niż .To, który odfiltrowuje .i..

Edycja: Usunięto -p z polecenia cp, ponieważ Asker nie wskazał, że chce zachować własność, daty itp.


Działa to w przypadku przykładowych nazw plików i katalogów podanych w pytaniu, ale w tekście pytania jest napisane „ukryte pliki i ukryte podkatalogi (te zaczynające się od kropki)”, a ta odpowiedź nie znajdzie plików i katalogów, których nazwy zaczynają się od dwie kropki; np ..c.
Scott

To dość ostry przypadek, ale jednak uzasadniona obawa. Nie zastanawiałem się nad tym. Możesz to wyjaśnić, przełączając się na, .*[^.]ale wtedy przegapisz pliki, które kończą się na .. Myślę, że naprawdę potrzebujesz rozszerzonego globowania, aby naprawdę uwzględnić wszystkie przypadki.
Wszechobecność

4

Problem A/.*polega na tym, że istnieje katalog, .w Aktórym również pasuje do wzorca.

Możesz włączyć rozszerzone wzorce globów i użyć następujących opcji:

shopt -s extglob
cp -r A/.!(?(.)) B    

Pasuje do plików, których nazwa zaczyna się od kropki i których drugim znakiem nie jest ani kropka, ani nic (? (.) Nie pasuje do nic lub kropki,! (...) neguje to znaczy!! (? (.)) Pasuje do wszystkiego innego niż nic lub kropka).


+1 za poprawną odpowiedź. Zauważ, że .!(@(|.))jest to (AFAICT) równoważne z powyższym, (IMNSHO) jest trochę wyraźniejsze i tylko jedna postać jest dłuższa.
Scott

3

W takich przypadkach zaleca się użycie findzamiast cptego:

find A/ -type f -maxdepth 1 -name '.*' -exec cp -p {} B/ \;

Podstawowa składnia dzieli się następująco:

  • find A/ -type f: findelementy w katalogu, A/którego typem jest plik (zamiast katalogu)…
  • -maxdepth 1 -name '.*': Do tego dla jednego maxdepthz katalogów i od którego namezaczyna się ..
  • -exec cp -p {} B/ \;: A kiedy znajdują się te pliki, komenda z flagą zachować dat / razy od źródła ( ) do miejsca przeznaczenia .execcp-p{}B/

Lubię maxdepthdodawać warstwę kontrolną, więc nie kopiuję przypadkowo całego systemu plików. Ale możesz to usunąć.


0
 for item in `find A -type d | grep -E "\."` ; do cp -r $item B ; done
  • find A -type d zapewnia listę rekurencyjną w obrębie A zawierającą tylko katalogi
  • grep -E "\." filtruje katalogi kropką (tzn. ukryte katalogi)
  • potrzebna była tutaj opcja -E, ponieważ bez niej oznacza to również „bieżący katalog”
  • odwrotnym ukośnikiem jest uniknięcie znaczenia wyrażenia „dowolny znak” w wyrażeniu regularnym
  • cp -r kopiować rekurencyjnie

Utworzyłem strukturę plików i folderów dla A i wykonałem polecenie w Git Bash (w tej chwili nie mam Linuksa) i zadziałało.


Dzieje się tak, jeśli pliki mają białe znaki lub znaki specjalne w nazwie lub ścieżce.
slhck

Dzięki za zauważenie :) Właściwie ograniczyłem się do „przypadku testowego” autorstwa @gaboroncancio. Jeśli możesz dać mi inną baterię testową, mogę spróbować to poprawić (oczywiście, jeśli chcesz,
popraw

Możesz po prostu umieścić pliki kropkowe w folderze o nazwie A B, a wtedy zadziałałoby to nieoczekiwanie, ponieważ rozwinąłoby się do cp -r A B/.dotfile B. Ogólna rada to w ogóle nie analizować findani lsgenerować wyników . Jeśli używasz find, powinieneś również użyć własnych opcji do filtrowania grep, a jeśli findprzesyłasz dane wyjściowe gdzie indziej, użyj -print0lub bezpośrednio wywołaj żądane polecenie. Zobacz find instrukcję .
slhck

Nawet bardziej ogólnie, podczas pracy z plikami najbezpieczniej jest używać globów powłoki, jak wyjaśniono w innych odpowiedziach (choć często wymagają extglobone ustawienia).
slhck

Dzięki za link. Zostawmy więc findparsowanie.
malarres

0

Alternatywnie możesz użyć tego innego polecenia, jeśli drugi znak jest alfanumeryczny ( źródło ):

cp -r A/.[a-zA-Z0-9]* B

Działa to w przypadku przykładowych nazw plików i katalogów podanych w pytaniu, ale w tekście pytania jest napisane „ukryte pliki i ukryte podkatalogi (te zaczynające się od kropki)”, a ta odpowiedź nie znajdzie plików i katalogów, których nazwy zaczynają się od kropka i znak specjalny; np . .@foolub ..c.
Scott

Dlatego wskazuję, że działa, jeśli drugi znak jest alfanumeryczny. ;)
gaboroncancio
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.