Kopieer een specifiek bestandstype met behoud van de mapstructuur
Geplaatst op februari 10, 2021 door adminIk heb een mappenstructuur met een heleboel * .csv-bestanden verspreid over de mappen. Nu wil ik alle * .csv-bestanden naar een andere bestemming kopiëren met behoud van de mappenstructuur.
Het werkt door:
cp --parents *.csv /target cp --parents */*.csv" /target cp --parents */*/*.csv /target cp --parents */*/*/*.csv /target ...
en enzovoort, maar ik zou het graag met één commando willen doen.
Antwoord
find
heeft een zeer handige -exec
optie:
find . -name "*.csv" -exec cp --parents \{\} /target \;
Reacties
- Waarschijnlijk hierdoor \ {\} \;
-
'{}'
werkt net zo goed - Hoewel
-execdir
is veiliger dan-exec
, door simpelweg de ene door de andere te vervangen, blijft de mapstructuur niet behouden zoals bedoeld. - Waarom ik krijg bericht ‘ Directory ‘ weglaten wanneer ik ze probeer te kopiëren met jouw commando?
- Kun je uitleggen waarom de accolades moeten hier worden ontsnapt?
Antwoord
Je kunt ook rsync
voor dit.
$ rsync -a --prune-empty-dirs --include "*/" --include "*.csv" --exclude "*" source/ target/
Als je lege mappen uit de broncodestructuur wilt behouden, sla dan de --prune-empty-dirs
optie over:
$ rsync -a --include "*/" --include "*.csv" --exclude "*" source/ target/
Als u niet symlinks, wijzigingsdatums, bestandsrechten, eigenaren etc. wilt behouden, vervang dan -a
met een andere combinatie van -rlptgoD
. 😉
Reacties
Antwoord
U kunt find en cpio in pass-through-modus
find . -name "*.csv" | cpio -pdm /target
Hiermee worden alle .csv-bestanden gevonden in de huidige directory en daaronder en kopieer ze naar / target met behoud van de directorystructuur die is geworteld in .
.
Als u
het zal het hele bestand in /path/to/files
en lager vinden en ze kopiëren naar /target/path/to/files
en lager .
Reacties
- Ik heb alle antwoorden van boven naar beneden geprobeerd, en dit was de enige die werkte bij de eerste poging
- Dit zou het geaccepteerde antwoord moeten zijn.
- Ik vond de GNU-documenten nuttig: ” In copy-pass mode, [aangevraagd door de
-p
optie, cpio] leest de lijst met te kopiëren bestanden van de standaard input; de map waarin het ze zal kopiëren, wordt opgegeven als een niet-optieargument. ” … ” -d Maak waar nodig toonaangevende mappen. ” … ” -m Bewaar eerdere bestandswijzigingstijden bij het aanmaken van bestanden. ”
Antwoord
Het cp
commando staat meerdere bronargumenten toe:
cp **/*.csv --parents ../target
CAVEAT: Ik “gebruik hier een recursieve glob; dit is de globstar
optie in Bash 4+ en ksh
, en wordt standaard ondersteund in zsh
. Recursieve globs niet komen overeen met verborgen bestanden en mappen, en de volgen sommige implementaties symlinks en andere niet .
Als uw shell dat niet doet ” t supp ort recursieve klodders, of als u “liever ze niet gebruikt, kunt u het volgende doen:
-
*.csv */*.csv */*/*.csv */*/*/*.csv
– dit is natuurlijk erg redundant en vereist dat u weet hoe diep uw directorystructuur is. -
$(find . -name "*.csv")
– Deze zal komen overeen met verborgen bestanden en mappen.find
ondersteunt ook het specificeren of symlinks worden gevolgd, wat handig kan zijn.
Reacties
- dit is precies wat ik heb geprobeerd (de recursieve glob) en er zijn er enkele gevonden, maar niet alle? Best wel raar. Ik kreeg exact hetzelfde resultaat bij het gebruik van het npm copyfiles-script, maar als ik het find-commando gebruik, vindt het alles …
- @Randyaa Ik ‘ heb wat nodig meer details over welke bestanden precies ‘ t werden gevonden om u te helpen. Mogelijk vindt u de discussie hier en wordt hier voortgezet over het precieze gedrag van de recursieve glob die nuttig is .
- blijkt dat recursieve glob niet ‘ t was ingeschakeld om de een of andere reden …Ik ‘ ben dit nog nooit eerder tegengekomen, maar ik heb het gecorrigeerd met een uitvoering van
shopt -s globstar
onmiddellijk voor mijn commando en alles is in orde. Bedankt voor het vervolg! -
--parents
was wat ik zocht. bedankt
Antwoord
Deze werkte voor mij:
find -name "*.csv" | xargs cp --parents -t /target
Reacties
- Beste antwoord met de meest eenvoudige syntaxis. Werkt prima en is gemakkelijk te onthouden. In veel gevallen is
find [things] | xargs [do stuff]
erg krachtig. - Akkoord. Zeer eenvoudig vergeleken met sommige van de andere antwoorden.
- Onderbrekingen als je spaties in bestandsnamen hebt
- @MichelePiccolini Spaties in bestandsnamen kunnen worden afgehandeld met
find -print0
enxargs -0
.
Antwoord
Van rsync
“s manpage:
-R, –relative
Gebruik relatieve paden. Dit betekent dat de volledige padnamen die op de opdrachtregel zijn opgegeven, naar de server worden gestuurd in plaats van alleen de laatste delen van de bestandsnamen. Dit is met name handig als u meerdere mappen tegelijkertijd wilt verzenden. Als u bijvoorbeeld dit commando:
rsync -av /foo/bar/baz.c remote:/tmp/
… dit zou een bestand genaamd baz.c creëren in / tmp / op de externe machine. Als je in plaats daarvan
rsync -avR /foo/bar/baz.c remote:/tmp/
dan zou een bestand met de naam /tmp/foo/bar/baz.c worden aangemaakt op de externe machine, met behoud van het volledige pad. Deze extra padelementen worden ” impli ed directories “(d.w.z. de “foo” en de “foo / bar” directories in het bovenstaande voorbeeld).
Dus dit zou ook werken:
rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
Reacties
- Bedankt voor het geven van dit antwoord. Compatibel met BSD-gebruikersland (macOS), en paden met spaties erin.
Answer
Ervan uitgaande dat u deze structuur wilt repliceren van ./source
naar ./destination
:
cd source find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)
Ik ben bereid dat als één regel te tellen, waarbij de cd source
een ingebouwde shell is.
Opmerkingen
-
tar
heeft de-C
optie om te voorkomen dat je eerst de directory moet veranderen.
-m
is een snelkoppeling voor--prune-emty-dirs
.-R
worden toegevoegd om de bovenliggende directorystructuur van de broncode te kopiëren. (zie mijn antwoord hier.)