Skopiuj określony typ pliku, zachowując strukturę folderów
On 10 lutego, 2021 by adminMam strukturę folderów z wieloma plikami * .csv rozrzuconymi po folderach. Teraz chcę skopiować wszystkie pliki * .csv do innego miejsca docelowego, zachowując strukturę folderów.
Działa to w następujący sposób:
cp --parents *.csv /target cp --parents */*.csv" /target cp --parents */*/*.csv /target cp --parents */*/*/*.csv /target ...
i tak dalej, ale chciałbym to zrobić jednym poleceniem.
Odpowiedz
find
ma bardzo przydatną -exec
opcję:
find . -name "*.csv" -exec cp --parents \{\} /target \;
Komentarze
- Prawdopodobnie z tego powodu \ {\} \;
-
'{}'
działa równie dobrze - Mimo że
-execdir
jest bezpieczniejsze niż-exec
, po prostu zastąpienie jednego innym nie zachowuje struktury folderów zgodnie z przeznaczeniem. - Dlaczego ja otrzymuję wiadomość ' Pomijam katalog ', gdy próbuję je skopiować za pomocą Twojego polecenia?
- Czy możesz wyjaśnić, dlaczego w tym miejscu należy wprowadzić znaki zmiany znaczenia?
Odpowiedź
Możesz również użyć rsync
dla to.
$ rsync -a --prune-empty-dirs --include "*/" --include "*.csv" --exclude "*" source/ target/
Jeśli chcesz zachować puste katalogi z drzewa źródłowego, pomiń opcję --prune-empty-dirs
:
$ rsync -a --include "*/" --include "*.csv" --exclude "*" source/ target/
Jeśli nie chcesz zachować linków symbolicznych, dat modyfikacji, uprawnień do plików, właścicieli itp., zamień -a
z inną kombinacją -rlptgoD
. 😉
Komentarze
Odpowiedź
Możesz użyć find i cpio w trybie tranzytowym
find . -name "*.csv" | cpio -pdm /target
Spowoduje to znalezienie wszystkich plików .csv w bieżącym katalogu i niższych i skopiuj je do / target, zachowując strukturę katalogów zakorzenioną w .
.
Jeśli używasz
find /path/to/files -name "*.csv" | cpio -pdm /target
znajdzie cały plik w /path/to/files
i niższych i skopiuje je do /target/path/to/files
i poniżej .
Komentarze
- Wypróbowałem wszystkie odpowiedzi z góry na dół do tej i jako jedyna działała za pierwszym razem
- To powinna być akceptowana odpowiedź.
- Pomogły mi dokumenty GNU : ” W trybie kopiowania z przejściem, [na żądanie opcji
-p
, cpio] czyta listę plików do skopiowania ze standardowego wejścia; katalog, do którego je skopiuje, jest podany jako argument niebędący opcją. ” … ” -d Utwórz wiodące katalogi w razie potrzeby. ” … ” -m Zachowaj poprzednie czasy modyfikacji plików podczas tworzenia plików. ”
Odpowiedź
Polecenie cp
zezwala na wiele argumentów źródłowych:
cp **/*.csv --parents ../target
OSTRZEŻENIE: Używam tutaj rekurencyjnej globalnej; to jest opcja globstar
w Bash 4+ i ksh
i jest domyślnie obsługiwany w zsh
. Rekursywne listy globalne nie dopasuj ukryte pliki i foldery oraz niektóre implementacje podążają za dowiązaniami symbolicznymi, a inne nie .
Jeśli twoja powłoka nie ” t przyp ort rekurencyjnych globów lub jeśli wolisz ich nie używać, możesz wykonać następujące czynności:
-
*.csv */*.csv */*/*.csv */*/*/*.csv
– to oczywiście bardzo zbędne i wymaga znajomości, jak głęboka jest struktura katalogów. -
$(find . -name "*.csv")
– To spowoduje dopasuj ukryte pliki i foldery.find
obsługuje również określanie, czy śledzone są łącza symboliczne, co może być przydatne.
Komentarze
- właśnie tego próbowałem (rekurencyjna glob) i znalazłem kilka, ale nie wszystkie? dość dziwne. Otrzymałem dokładnie ten sam wynik, używając skryptu npm copyfiles, ale jeśli użyję polecenia find, znajdzie wszystko …
- @Randyaa I ' będę potrzebować trochę więcej szczegółów o tym, które dokładnie ' plików nie znaleźliśmy, aby ci pomóc. Możesz znaleźć dyskusję tutaj i kontynuowaną tutaj na temat dokładnego zachowania rekurencyjnej globu, użytecznej .
- okazuje się, że rekurencyjny glob nie był ' z jakiegoś powodu włączony …' nigdy wcześniej tego nie spotkałem, ale poprawiłem to, wykonując
shopt -s globstar
bezpośrednio przed poleceniem i wszystko jest w porządku. Dzięki za kontynuację! -
--parents
było tym, czego szukałem. dzięki
Odpowiedź
Ten zadziałał dla mnie:
find -name "*.csv" | xargs cp --parents -t /target
Komentarze
- Najlepsza odpowiedź z najprostszą składnią. Działa dobrze i jest łatwy do zapamiętania. W wielu przypadkach
find [things] | xargs [do stuff]
jest bardzo potężny. - Zgoda. Bardzo proste w porównaniu z niektórymi innymi odpowiedziami.
- Przerwy, jeśli masz spacje w nazwach plików
- @MichelePiccolini Spacje w nazwach plików można obsłużyć za pomocą
find -print0
ixargs -0
.
Odpowiedź
Z rsync
„s manpage:
-R, –relative
Używaj ścieżek względnych. Oznacza to, że do serwera wysyłane są pełne nazwy ścieżek podane w wierszu poleceń, a nie tylko ostatnie części nazw plików. Jest to szczególnie przydatne, gdy chcesz wysłać kilka różnych katalogów w tym samym czasie. Na przykład, jeśli użyłeś to polecenie:
rsync -av /foo/bar/baz.c remote:/tmp/
… to utworzy plik o nazwie baz.c w / tmp / na zdalnym komputerze. Jeśli zamiast tego użyjesz
rsync -avR /foo/bar/baz.c remote:/tmp/
wtedy plik o nazwie /tmp/foo/bar/baz.c zostałby utworzony na zdalnym komputerze z zachowaniem pełnej ścieżki. Te dodatkowe elementy ścieżki noszą nazwę „ impli ed katalogi ”(tj. katalogi „foo” i „foo / bar” w powyższym przykładzie).
To też zadziała:
rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
Komentarze
- Dziękujemy za udzielenie tej odpowiedzi. Kompatybilny ze ścieżkami BSD (macOS), i ze spacjami.
Odpowiedź
Zakładając, że chcesz powielić tę strukturę z ./source
do ./destination
:
cd source find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)
Jestem gotów policzyć to jako jedną linię, cd source
jest wbudowaną powłoką.
Komentarze
-
tar
ma opcję-C
, aby uniknąć konieczności wcześniejszej zmiany katalogu.
-m
to skrót do--prune-emty-dirs
.-R
można dodać w celu skopiowania struktury katalogu nadrzędnego źródła. (por. moją odpowiedź tutaj.)