Copiați tipul de fișier specific păstrând structura folderelor
On februarie 10, 2021 by adminAm o structură de dosare cu o grămadă de fișiere * .csv împrăștiate prin foldere. Acum vreau să copiez toate fișierele * .csv într-o altă destinație păstrând structura folderelor.
Funcționează făcând:
cp --parents *.csv /target cp --parents */*.csv" /target cp --parents */*/*.csv /target cp --parents */*/*/*.csv /target ...
și așa mai departe, dar aș dori să o fac folosind o singură comandă.
Răspuns
find
are o opțiune foarte utilă -exec
:
find . -name "*.csv" -exec cp --parents \{\} /target \;
Comentarii
- Probabil din această cauză \ {\} \;
-
'{}'
funcționează la fel de bine - Chiar dacă
-execdir
este mai sigur decât-exec
, simpla înlocuire a unuia cu cealaltă nu păstrează structura folderelor așa cum se intenționează. - De ce primiți mesaj ‘ Omitând directorul ‘ când încerc să le copiez cu comanda dvs.?
- Puteți explica de ce paranteze trebuie scăpate aici?
Răspuns
Puteți utiliza și rsync
pentru aceasta.
$ rsync -a --prune-empty-dirs --include "*/" --include "*.csv" --exclude "*" source/ target/
Dacă doriți să păstrați directoare goale din arborele sursă, săriți opțiunea --prune-empty-dirs
:
$ rsync -a --include "*/" --include "*.csv" --exclude "*" source/ target/
Dacă nu doriți să se păstreze link-uri simbolice, date de modificare, permisiuni de fișiere, proprietari etc., înlocuiți -a
cu o altă combinație de -rlptgoD
. 😉
Comentarii
Răspuns
Puteți utiliza găsi și cpio în modul de trecere
find . -name "*.csv" | cpio -pdm /target
Aceasta va găsi toate fișierele .csv în directorul curent și mai jos și copiați-le în / target menținând structura directorului înrădăcinată în .
.
Dacă utilizați
find /path/to/files -name "*.csv" | cpio -pdm /target
va găsi tot fișierul în /path/to/files
și mai jos și le va copia în /target/path/to/files
și mai jos .
Comentarii
- Am încercat toate răspunsurile de sus în jos până la acesta și acesta a fost singurul care a funcționat la prima încercare
- Acesta ar trebui să fie răspunsul acceptat.
- Am găsit de ajutor documente GNU : ” În modul copy-pass, [solicitat de opțiunea
-p
, cpio] citește lista fișierelor de copiat din intrarea standard; directorul în care le va copia este dat ca argument fără opțiune. ” … ” -d Creați directoare de conducere acolo unde este necesar. ” … ” -m Păstrează timpii anteriori de modificare a fișierului la crearea fișierelor. ”
Răspuns
Comanda cp
permite mai multe argumente sursă:
cp **/*.csv --parents ../target
CAVEAT: Utilizez un glob recursiv aici; aceasta este opțiunea globstar
în Bash 4+ și ksh
și este acceptat implicit în zsh
. Globuri recursive nu se potrivesc cu fișierele și folderele ascunse, iar unele implementări urmează link-uri simbolice, în timp ce altele nu .
Dacă shell-ul dvs. nu face acest lucru ” t supp sau globuri recursive sau, dacă preferați să nu le utilizați, puteți face următoarele:
-
*.csv */*.csv */*/*.csv */*/*/*.csv
– acest lucru este, desigur, foarte redundant și necesită cunoașterea cât de profundă este structura dvs. de director. -
$(find . -name "*.csv")
– Acest va potrivesc fișierele și folderele ascunse.find
acceptă, de asemenea, specificarea dacă sunt sau nu urmate link-uri simbolice, ceea ce poate fi util.
Comentarii
- exact asta am încercat (globul recursiv) și a găsit unele, dar nu toate? destul de ciudat. Am obținut același rezultat exact când folosesc scriptul npm copyfiles, dar dacă folosesc comanda find, găsește totul …
- @Randyaa Am ‘ voi avea nevoie de ceva mai multe detalii despre ce fișiere, exact, nu au fost ‘ găsite pentru a vă ajuta. Puteți găsi discuția aici și a continuat aici despre comportamentul precis al globului recursiv .
- se dovedește că globul recursiv nu a fost activat ‘ din anumite motive …’ nu am mai întâlnit acest lucru înainte, dar l-am corectat doar cu o execuție a
shopt -s globstar
imediat înainte de comanda mea și totul este bine. Vă mulțumim pentru urmărire! -
--parents
a fost ceea ce căutam. mulțumesc
Răspuns
Acesta a funcționat pentru mine:
find -name "*.csv" | xargs cp --parents -t /target
Comentarii
- Cel mai bun răspuns cu cea mai simplă sintaxă. Funcționează foarte bine și este ușor de reținut. În multe cazuri,
find [things] | xargs [do stuff]
este foarte puternic. - De acord. Foarte simplu în comparație cu unele dintre celelalte răspunsuri.
- Pauzele dacă aveți spații în numele fișierelor
- @MichelePiccolini Spațiile din numele fișierelor pot fi tratate cu
find -print0
șixargs -0
.
Răspuns
De la rsync
„pagina de manual:
-R, –relative
Utilizați căi relative. Aceasta înseamnă că numele complete ale căilor specificate pe linia de comandă sunt trimise către server, nu doar ultimele părți ale numelor de fișiere. Acest lucru este util mai ales atunci când doriți să trimiteți mai multe directoare diferite în același timp. această comandă:
rsync -av /foo/bar/baz.c remote:/tmp/
… aceasta ar crea un fișier numit baz.c în / tmp / pe mașina de la distanță. Dacă în schimb ați utiliza
rsync -avR /foo/bar/baz.c remote:/tmp/
atunci un fișier numit /tmp/foo/bar/baz.c ar fi creat pe computerul de la distanță, păstrându-și calea completă. Aceste elemente de cale suplimentare se numesc ” impli directoare ed „(adică directorul „foo” și „foo / bar” din exemplul de mai sus).
Deci, și asta ar funcționa:
rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
Comentarii
- Vă mulțumim că ați oferit acest răspuns. Compatibil cu BSD userland (macOS), și căi cu spații în ele.
Răspuns
Presupunând că doriți să reproduceți această structură de la ./source
la ./destination
:
cd source find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)
Sunt „pregătit să număr asta ca pe o singură linie, cd source
fiind un shell integrat.
Comentarii
tar
are opțiunea -C
pentru a evita să fie nevoie să schimbați mai întâi directorul.
-m
este o comandă rapidă pentru--prune-emty-dirs
.-R
poate fi adăugată pentru a copia structura directorului părinte a sursei. (cf. răspunsul meu aici.)