Linux: kopieer en maak bestemmingsmap als deze niet bestaat

Ik wil een commando (of waarschijnlijk een optie voor cp) die de doelmap aanmaakt als deze niet bestaat.

Voorbeeld:

cp -? file /path/to/copy/file/to/is/very/deep/there

Antwoord 1, autoriteit 100%

mkdir -p "$d" && cp file "$d"

(er is geen dergelijke optie voor cp).


Antwoord 2, autoriteit 60%

Als het volgende waar is:

  1. U gebruikt de GNU-versie van cp(en niet bijvoorbeeld de Mac-versie), en
  2. U kopieert van een bestaande directorystructuur en u moet deze alleen opnieuw maken

dan kun je dit doen met de --parentsvlag van cp. Vanaf de infopagina (te bekijken op http://www.gnu.org /software/coreutils/manual/html_node/cp-invocation.html#cp-invocationof met info cpof man cp):

--parents
     Form the name of each destination file by appending to the target
     directory a slash and the specified name of the source file.  The
     last argument given to `cp' must be the name of an existing
     directory.  For example, the command:
          cp --parents a/b/c existing_dir
     copies the file `a/b/c' to `existing_dir/a/b/c', creating any
     missing intermediate directories.

Voorbeeld:

/tmp $ mkdir foo
/tmp $ mkdir foo/foo
/tmp $ touch foo/foo/foo.txt
/tmp $ mkdir bar
/tmp $ cp --parents foo/foo/foo.txt bar
/tmp $ ls bar/foo/foo
foo.txt

Antwoord 3, autoriteit 25%

Kort antwoord

Om myfile.txtte kopiëren naar /foo/bar/myfile.txt, gebruik je:

mkdir -p /foo/bar && cp myfile.txt $_

Hoe werkt dit?

Er zijn een paar componenten, dus ik zal de hele syntaxis stap voor stap behandelen.

Het hulpprogramma mkdir, zoals gespecificeerd in de POSIX-standaard, maakt mappen. Het argument -p, volgens de documenten, zorgt ervoor dat mkdir

Maak eventuele ontbrekende tussenliggende padnaamcomponenten

wat betekent dat bij het aanroepen van mkdir -p /foo/bar, mkdir/fooen/foo/barals /foonog niet bestaat. (Zonder -pzal het in plaats daarvan een foutmelding geven.

De &&lijstoperator, zoals gedocumenteerd in de POSIX-standaard(of de Bash-handleidingals je wilt), heeft de effect dat cp myfile.txt $_alleen wordt uitgevoerd als mkdir -p /foo/barsuccesvol wordt uitgevoerd. Dit betekent dat de opdracht cpniet zal proberen uit te voeren als mkdirfaalt voor een van de vele redenen waarom het zou kunnen mislukken.

Ten slotte is de $_die we als tweede argument doorgeven aan cpeen “speciale parameter” die handig kan zijn om herhaling van lange argumenten (zoals bestandspaden) te voorkomen zonder ze in een variabele op te slaan. Volgens de Bash-handleiding, is het:

uitbreidt tot het laatste argument van het vorige commando

In dit geval is dat de /foo/bardie we hebben doorgegeven aan mkdir. Dus het cpcommando breidt uit naar cp myfile.txt /foo/bar, dat myfile.txtkopieert naar de nieuw aangemaakte /foo/barmap.

Merk op dat $_nietonderdeel van de POSIX-standaard, dus theoretisch zou een Unix-variant een shell kunnen hebben die deze constructie niet ondersteunt. Ik ken echter geen moderne shells die $_niet ondersteunen; zeker Bash, Dash en zsh doen dat allemaal.


Een laatste opmerking: de opdracht die ik aan het begin van dit antwoord heb gegeven, gaat ervan uit dat de namen van uw directory’s geen spaties bevatten. Als u te maken heeft met namen met spaties, moet u deze citeren zodat de verschillende woorden worden niet behandeld als verschillende argumenten voor mkdirof cp. Dus je commando zou er eigenlijk als volgt uitzien:

mkdir -p "/my directory/name with/spaces" && cp "my filename with spaces.txt" "$_"

Antwoord 4, autoriteit 10%

Zo’n oude vraag, maar misschien kan ik een alternatieve oplossing voorstellen.

U kunt het programma installgebruiken om uw bestand te kopiëren en het bestemmingspad “on the fly” te maken.

install -D file /path/to/copy/file/to/is/very/deep/there/file

Er zijn echter enkele aspecten waarmee u rekening moet houden:

  1. u moet ook de naam van het doelbestand specificeren, niet alleen het doelpad
  2. het doelbestand zal uitvoerbaar zijn(tenminste, voor zover ik uit mijn tests heb gezien)

Je kunt #2 gemakkelijk wijzigen door de optie -mtoe te voegen om machtigingen voor het doelbestand in te stellen (voorbeeld: -m 664maakt het doelbestand met machtigingen rw-rw-r--, net zoals het maken van een nieuw bestand met touch).


En hier is het de schaamteloze link naar het antwoord waar ik door werd geïnspireerd=)


Antwoord 5, autoriteit 5%

Shell-functie die doet wat je wilt en het een “begraaf”-kopie noemt omdat het een gat graaft waar het bestand in kan leven:

bury_copy() { mkdir -p `dirname $2` && cp "$1" "$2"; }

Antwoord 6, autoriteit 3%

Hier is een manier om het te doen:

mkdir -p `dirname /path/to/copy/file/to/is/very/deep/there` \
   && cp -r file /path/to/copy/file/to/is/very/deep/there

dirnamegeeft je de ouder van de doelmap of het doelbestand. mkdir -p `dirname …` maakt dan die map aan en zorgt ervoor dat wanneer je cp -r aanroept, de juiste basismap aanwezig is.

Het voordeel hiervan ten opzichte van –parents is dat het werkt voor het geval dat het laatste element in het doelpad een bestandsnaam is.

En het werkt ook op OS X.


Antwoord 7, autoriteit 2%

install -D file -m 644 -t /path/to/copy/file/to/is/very/deep/there


Antwoord 8

met alle respect voor bovenstaande antwoorden, gebruik ik rsync het liefst als volgt:

$  rsync -a directory_name /path_where_to_inject_your_directory/

voorbeeld:

$ rsync -a test /usr/local/lib/

Antwoord 9

Om maar weer verder te gaan en een compleet werkende oplossing te geven, in één regel.
Wees voorzichtig als je je bestand wilt hernoemen, je moet een manier toevoegen om een ​​schoon dir-pad naar mkdir te geven. $fdst kan bestand of dir zijn.
De volgende code zou in ieder geval moeten werken.

fsrc=/tmp/myfile.unk
fdst=/tmp/dir1/dir2/dir3/myfile.txt
mkdir -p $(dirname ${fdst}) && cp -p ${fsrc} ${fdst}

of bash-specifiek

fsrc=/tmp/myfile.unk
fdst=/tmp/dir1/dir2/dir3/myfile.txt
mkdir -p ${fdst%/*} && cp -p ${fsrc} ${fdst}

Antwoord 10

Voeg eenvoudig het volgende toe aan uw .bashrc, pas aan indien nodig. Werkt in Ubuntu.

mkcp() {
    test -d "$2" || mkdir -p "$2"
    cp -r "$1" "$2"
}

Bijvoorbeeld
Als u het ‘test’-bestand naar de doelmap ‘d’ wilt kopiëren
Gebruik,

mkcp test a/b/c/d

mkcpzal eerst controleren of de bestemmingsmap bestaat of niet, zo niet, maak deze dan en kopieer het bronbestand/de map.


Antwoord 11

Zoals hierboven gesuggereerd door help_asap en spongeman, kunt u het ‘install’-commando gebruiken om bestanden naar bestaande mappen te kopiëren of nieuwe doelmappen te maken als ze nog niet bestaan.

Optie 1
install -D filename some/deep/directory/filename
kopieert bestand naar een nieuwe of bestaande map en geeft bestandsnaam standaard 755 permissies

Optie 2
install -D filename -m640 some/deep/directory/filename
volgens optie 1 maar geeft bestandsnaam 640 rechten.

Optie 3
install -D filename -m640 -t some/deep/directory/
volgens optie 2, maar de bestandsnaam wordt in de doelmap geplaatst, zodat de bestandsnaam niet zowel in de bron als in het doel hoeft te worden geschreven.

Optie 4
install -D filena* -m640 -t some/deep/directory/
volgens optie 3 maar gebruikt een wildcard voor meerdere bestanden.

Het werkt goed in Ubuntu en combineert twee stappen (aanmaken van mappen en kopiëren van bestanden) in één enkele stap.


Antwoord 12

Dit doet het voor mij

cp -vaR ./from ./to

Antwoord 13

Ik heb een ondersteuningsscript voor cp geschreven, CP genaamd (let op hoofdletters), dat precies dit moet doen. Script zal controleren op fouten in het pad dat je hebt ingevoerd (behalve de laatste die de bestemming is) en als alles goed is, zal het een mkdir -p stap uitvoeren om het bestemmingspad te creëren voordat het kopiëren begint. Op dit punt neemt het reguliere cp-hulpprogramma het over en alle schakelaars die u gebruikt met CP (zoals -r, -p, -rpL worden rechtstreeks naar cp doorgesluisd). Voordat je mijn script gebruikt, zijn er een paar dingen die je moet begrijpen.

  • alle informatie hier is toegankelijk via CP –help. CP –help-all include’s cp’s switches.
  • gewone cp zal de kopie niet doen als het het bestemmingspad niet vindt. Zo’n vangnet voor typefouten heb je met CP niet. Je bestemming wordt gemaakt, dus als je je bestemming verkeerd spelt als /usrr/share/icons of /usr/share/icon well, dan wordt dat gemaakt.
  • reguliere cp heeft de neiging om zijn gedrag te modelleren op het bestaande pad: cp /a/b /c/d zal variëren naargelang d al dan niet bestaat. als d een bestaande map is, zal cp b erin kopiëren, waardoor /c/d/b. Als d niet bestaat, wordt b gekopieerd naar c en hernoemd naar d. Als d bestaat maar een bestand is en b een bestand is, wordt het overschreven door de kopie van b. Als c niet bestaat, doet cp het kopiëren niet en sluit het af.

CP heeft niet de luxe om aanwijzingen van bestaande paden te nemen, dus het moet een aantal zeer vaste gedragspatronen hebben. CP gaat ervan uit dat het item dat u kopieert in het doelpad wordt geplaatst en niet de bestemming zelf is (ook wel een hernoemde kopie van het bronbestand/de bronmap). Betekenis:

  • “CP /a/b /c/d” zal resulteren in /c/d/b als d een map is
  • “CP /a/b /c/b” zal resulteren in /c/b/b als b in /c/b een map is.
  • Als zowel b als d bestanden zijn: CP /a/b /c/d resulteert in /c/d (waarbij d een kopie is van b). Hetzelfde geldt voor CP /a/b /c/b in dezelfde omstandigheden.

Dit standaard CP-gedrag kan worden gewijzigd met de schakelaar “–rename”. In dit geval wordt aangenomen dat

  • “CP –rename /a/b /c/d” kopieert b naar /c en hernoemt de kopie naar d.

Een paar afsluitende opmerkingen: net als bij cp kan CP meerdere items tegelijk kopiëren, waarbij wordt aangenomen dat het laatste pad de bestemming is. Het kan ook paden met spaties aan, zolang u aanhalingstekens gebruikt.

CP zal de paden die u invoert controleren en ervoor zorgen dat ze bestaan ​​voordat de kopie wordt uitgevoerd. In de strikte modus (beschikbaar via –strict switch), moeten alle bestanden/mappen die worden gekopieerd, bestaan, anders vindt er geen kopie plaats. In de ontspannen modus (–ontspannen) gaat het kopiëren verder als ten minste een van de items die u opsomt, bestaat. De standaardmodus is de ontspannen modus, u kunt de modus tijdelijk wijzigen via de schakelaars of permanent door de variabele easy_going aan het begin van het script in te stellen.

Zo installeer je het:

Doe in een niet-root-terminal:

sudo echo > /usr/bin/CP; sudo chmod +x /usr/bin/CP; sudo touch /usr/bin/CP
gedit admin:///usr/bin/CP 

Plak in gedit het CP-hulpprogramma en sla op:

#!/bin/bash
#Regular cp works with the assumption that the destination path exists and if it doesn't, it will verify that it's parent directory does.
#eg: cp /a/b /c/d will give /c/d/b if folder path /c/d already exists but will give /c/d (where d is renamed copy of b) if /c/d doesn't exists but /c does.
#CP works differently, provided that d in /c/d isn't an existing file, it assumes that you're copying item into a folder path called /c/d and will create it if it doesn't exist. so CP /a/b /c/d will always give /c/d/b unless d is an existing file. If you put the --rename switch, it will assume that you're copying into /c and renaming the singl item you're copying from b to d at the destination. Again, if /c doesn't exist, it will be created. So CP --rename /a/b /c/d will give a /c/d and if there already a folder called /c/d, contents of b will be merged into d. 
#cp+ $source $destination
#mkdir -p /foo/bar && cp myfile "$_"
err=0 # error count
i=0 #item counter, doesn't include destination (starts at 1, ex. item1, item2 etc)
m=0 #cp switch counter (starts at 1, switch 1, switch2, etc)
n=1 # argument counter (aka the arguments inputed into script, those include both switches and items, aka: $1 $2 $3 $4 $5)
count_s=0
count_i=0
easy_going=true #determines how you deal with bad pathes in your copy, true will allow copy to continue provided one of the items being copied exists, false will exit script for one bad path. this setting can also be changed via the custom switches: --strict and --not-strict
verbal="-v"
  help="===============================================================================\
    \n         CREATIVE COPY SCRIPT (CP) -- written by thebunnyrules\
    \n===============================================================================\n
    \n This script (CP, note capital letters) is intended to supplement \
    \n your system's regular cp command (note uncapped letters). \n
    \n Script's function is to check if the destination path exists \
    \n before starting the copy. If it doesn't it will be created.\n    
    \n To make this happen, CP assumes that the item you're copying is \
    \n being dropped in the destination path and is not the destination\
    \n itself (aka, a renamed copy of the source file/folder). Meaning:\n 
    \n * \"CP /a/b /c/d\" will result in /c/d/b \
    \n * even if you write \"CP /a/b /c/b\", CP will create the path /a/b, \
    \n   resulting in /c/b/b. \n
    \n Of course, if /c/b or /c/d are existing files and /a/b is also a\
    \n file, the existing destination file will simply be overwritten. \
    \n This behavior can be changed with the \"--rename\" switch. In this\
    \n case, it's assumed that \"CP --rename /a/b /c/d\" is copying b into /c  \
    \n and renaming the copy to d.\n
    \n===============================================================================\
    \n        CP specific help: Switches and their Usages \
    \n===============================================================================\n
    \
    \n  --rename\tSee above. Ignored if copying more than one item. \n
    \n  --quiet\tCP is verbose by default. This quiets it.\n
    \n  --strict\tIf one+ of your files was not found, CP exits if\
    \n\t\tyou use --rename switch with multiple items, CP \
    \n\t\texits.\n
    \n  --relaxed\tIgnores bad paths unless they're all bad but warns\
    \n\t\tyou about them. Ignores in-appropriate rename switch\
    \n\t\twithout exiting. This is default behavior. You can \
    \n\t\tmake strict the default behavior by editing the \
    \n\t\tCP script and setting: \n
    \n\t\teasy_going=false.\n
    \n  --help-all\tShows help specific to cp (in addition to CP)."
cp_hlp="\n\nRegular cp command's switches will still work when using CP.\
    \nHere is the help out of the original cp command... \
    \n\n===============================================================================\
    \n          cp specific help: \
    \n===============================================================================\n"
outro1="\n******************************************************************************\
    \n******************************************************************************\
    \n******************************************************************************\
    \n        USE THIS SCRIPT WITH CARE, TYPOS WILL GIVE YOU PROBLEMS...\
    \n******************************************************************************\
    \n******************************* HIT q TO EXIT ********************************\
    \n******************************************************************************"
#count and classify arguments that were inputed into script, output help message if needed
while true; do
    eval input="\$$n"
    in_=${input::1}
    if [ -z "$input" -a $n = 1 ]; then input="--help"; fi 
    if [ "$input" = "-h" -o "$input" = "--help" -o "$input" = "-?" -o "$input" = "--help-all" ]; then
        if [ "$input" = "--help-all" ]; then 
            echo -e "$help"$cp_hlp > /tmp/cp.hlp 
            cp --help >> /tmp/cp.hlp
            echo -e "$outro1" >> /tmp/cp.hlp
            cat /tmp/cp.hlp|less
            cat /tmp/cp.hlp
            rm /tmp/cp.hlp
        else
            echo -e "$help" "$outro1"|less
            echo -e "$help" "$outro1"
        fi
        exit
    fi
    if [ -z "$input" ]; then
        count_i=$(expr $count_i - 1 ) # remember, last item is destination and it's not included in cound
        break 
    elif [ "$in_" = "-" ]; then
        count_s=$(expr $count_s + 1 )
    else
        count_i=$(expr $count_i + 1 )
    fi
    n=$(expr $n + 1)
done
#error condition: no items to copy or no destination
    if [ $count_i -lt 0 ]; then 
            echo "Error: You haven't listed any items for copying. Exiting." # you didn't put any items for copying
    elif [ $count_i -lt 1 ]; then
            echo "Error: Copying usually involves a destination. Exiting." # you put one item and no destination
    fi
#reset the counter and grab content of arguments, aka: switches and item paths
n=1
while true; do
        eval input="\$$n" #input=$1,$2,$3,etc...
        in_=${input::1} #first letter of $input
        if [ "$in_" = "-" ]; then
            if [ "$input" = "--rename" ]; then 
                rename=true #my custom switches
            elif [ "$input" = "--strict" ]; then 
                easy_going=false #exit script if even one of the non-destinations item is not found
            elif [ "$input" = "--relaxed" ]; then 
                easy_going=true #continue script if at least one of the non-destination items is found
            elif [ "$input" = "--quiet" ]; then 
                verbal=""
            else
                #m=$(expr $m + 1);eval switch$m="$input" #input is a switch, if it's not one of the above, assume it belongs to cp.
                switch_list="$switch_list \"$input\""
            fi                                  
        elif ! [ -z "$input" ]; then #if it's not a switch and input is not empty, it's a path
                i=$(expr $i + 1)
                if [ ! -f "$input" -a ! -d "$input" -a "$i" -le "$count_i" ]; then 
                    err=$(expr $err + 1 ); error_list="$error_list\npath does not exit: \"b\""
                else
                    if [ "$i" -le "$count_i" ]; then 
                        eval item$i="$input" 
                        item_list="$item_list \"$input\""
                    else
                        destination="$input" #destination is last items entered
                    fi
                fi
        else
            i=0
            m=0
            n=1                     
            break
        fi      
        n=$(expr $n + 1)
done
#error condition: some or all item(s) being copied don't exist. easy_going: continue if at least one item exists, warn about rest, not easy_going: exit.
#echo "err=$err count_i=$count_i"
if [ "$easy_going" != true -a $err -gt 0 -a $err != $count_i ]; then 
    echo "Some of the paths you entered are incorrect. Script is running in strict mode and will therefore exit."
    echo -e "Bad Paths: $err $error_list"
    exit
fi
if [ $err = $count_i ]; then
    echo "ALL THE PATHS you have entered are incorrect! Exiting."
    echo -e "Bad Paths: $err $error_list"
fi
#one item to one destination:
#------------------------------
#assumes that destination is folder, it does't exist, it will create it. (so copying /a/b/c/d/firefox to /e/f/firefox will result in /e/f/firefox/firefox
#if -rename switch is given, will assume that the top element of destination path is the new name for the the item being given.
#multi-item to single destination:
#------------------------------
#assumes destination is a folder, gives error if it exists and it's a file. -rename switch will be ignored.
#ERROR CONDITIONS: 
# - multiple items being sent to a destination and it's a file.
# - if -rename switch was given and multiple items are being copied, rename switch will be ignored (easy_going). if not easy_going, exit.
# - rename option but source is folder, destination is file, exit.
# - rename option but source is file and destination is folder. easy_going: option ignored.
if [ -f "$destination" ]; then
    if [ $count_i -gt 1 ]; then 
        echo "Error: You've selected a single file as a destination and are copying multiple items to it. Exiting."; exit
    elif [ -d "$item1" ]; then
        echo "Error: Your destination is a file but your source is a folder. Exiting."; exit
    fi
fi
if [ "$rename" = true ]; then
    if [ $count_i -gt 1 ]; then
        if [ $easy_going = true ]; then
            echo "Warning: you choose the rename option but are copying multiple items. Ignoring Rename option. Continuing."
        else
            echo "Error: you choose the rename option but are copying multiple items. Script running in strict mode. Exiting."; exit
        fi
    elif [ -d "$destination" -a -f "$item1" ]; then
        echo -n "Warning: you choose the rename option but source is a file and destination is a folder with the same name. "
        if [ $easy_going = true ]; then
            echo "Ignoring Rename option. Continuing."
        else
            echo "Script running in strict mode. Exiting."; exit
        fi
    else
        dest_jr=$(dirname "$destination")
        if [ -d "$destination" ]; then item_list="$item1/*";fi
        mkdir -p "$dest_jr"
    fi
else
    mkdir -p "$destination"
fi
eval cp $switch_list $verbal $item_list "$destination"
cp_err="$?"
if [ "$cp_err" != 0 ]; then 
    echo -e "Something went wrong with the copy operation. \nExit Status: $cp_err"
else 
    echo "Copy operation exited with no errors."
fi
exit

Antwoord 14

cpheeft meerdere toepassingen:

$ cp --help
Usage: cp [OPTION]... [-T] SOURCE DEST
  or:  cp [OPTION]... SOURCE... DIRECTORY
  or:  cp [OPTION]... -t DIRECTORY SOURCE...
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

Het antwoord van @AndyRoss werkt voor de

cp SOURCE DEST

stijl van cp, maar doet het verkeerde als je de

. gebruikt

cp SOURCE... DIRECTORY/

stijl van cp.

Ik denk dat “DEST” dubbelzinnig is zonder een schuine streep in dit gebruik (dwz waar de doelmap nog niet bestaat), wat misschien de reden is waarom cphier nooit een optie voor heeft toegevoegd .

Dus hier is mijn versie van deze functie die een slash afdwingt in de dest dir:

cp-p() {
  last=${@: -1}
  if [[ $# -ge 2 && "$last" == */ ]] ; then
    # cp SOURCE... DEST/
    mkdir -p "$last" && cp "$@"
  else
    echo "cp-p: (copy, creating parent dirs)"
    echo "cp-p: Usage: cp-p SOURCE... DEST/"
  fi
}

Antwoord 15

Net hetzelfde probleem gehad. Mijn aanpak was om de bestanden gewoon in een archief te plaatsen, zoals:

tar cf your_archive.tar file1 /path/to/file2 path/to/even/deeper/file3

tar slaat de bestanden automatisch op in de juiste structuur binnen het archief. Als je

. uitvoert

tar xf your_archive.tar

de bestanden worden uitgepakt in de gewenste directorystructuur.


Antwoord 16

Dit is erg laat, maar het kan een rookie ergens helpen. Als u ‘auto’ mappen moet maken, zou rsync uw beste vriend moeten zijn.
rsync /path/to/sourcefile /path/to/tragetdir/thatdoestexist/


Antwoord 17

ik raad dittoten zeerste aan.
werkt gewoon.

ditto my/location/poop.txt this/doesnt/exist/yet/poop.txt


Antwoord 18

Gewoon zonder een script te maken en met een eenvoudige opdracht …

mkdir -p /destination-folder/ && cp file-name /destination-folder/

Antwoord 19

Kopieer van bron naar een niet-bestaand pad

mkdir –p /destination && cp –r /source/ $_

OPMERKING: dit commando kopieert alle bestanden

cp –rvoor het kopiëren van alle mappen en de inhoud ervan

$_werken als bestemming die is gemaakt in de laatste opdracht


Antwoord 20

rsync file /path/to/copy/file/to/is/very/deep/there

Dit zou kunnen werken, als je de juiste soort rsynchebt.


Antwoord 21

Je kunt findgebruiken met Perl. Opdracht zal als volgt zijn:

find file | perl -lne '$t = "/path/to/copy/file/to/is/very/deep/there/"; /^(.+)\/.+$/; `mkdir -p $t$1` unless(-d "$t$1"); `cp $_ $t$_` unless(-f "$t$_");'

Deze opdracht zal directory $taanmaken als deze nog niet bestaat. En kopieer dan filealleen naar $ttenzij filebestaat binnen $t.


Antwoord 22

Dit werkt op GNU /bin/bash versie 3.2 op MacOS (getest op zowel Catalina als Big Sur)

cp -Rv <existing-source-folder>/   <non-existing-2becreated-destination-folder>

de “v” optie is voor uitgebreid.

En ik beschouw de optie “-R” als “Recursief”.

man’s volledige beschrijving van -R is:

Als source_file een directory aanduidt, kopieert cp de directory en de hele substructuur die op dat punt is verbonden. Als het source_file eindigt op een /, wordt de inhoud van de directory gekopieerd in plaats van de directory zelf. Deze optie zorgt er ook voor dat symbolische koppelingen worden gekopieerd in plaats van erdoorheen geleid, en dat cp speciale bestanden maakt in plaats van ze als normale bestanden te kopiëren. Gemaakte mappen hebben dezelfde modus als de corresponderende bronmap, niet gewijzigd door de umask van het proces.

In -R-modus zal cp doorgaan met kopiëren, zelfs als er fouten worden gedetecteerd.

Houd er rekening mee dat cp hard-linked bestanden als aparte bestanden kopieert. Als u harde links wilt behouden, overweeg dan om in plaats daarvan tar(1), cpio(1) of pax(1) te gebruiken.

In het onderstaande voorbeeld gebruik ik een “/” aan het einde van de bestaande map zodat het alle inhoud van de bestaande map (en niet de map zelf) naar de nieuwe map kopieert:

cp -Rv existingfolder/  newfolder

Probeer het.


Antwoord 23

Alleen voor macOS

rsync -R <source file path> destination_folder

Voor macOSwerkt de optie voor ouders van cpniet


Antwoord 24

Oneliner om een klein script te maken dat als subcommando kan worden gebruikt, bijvoorbeeld in find:

set +H; echo -e "#!/bin/sh\nmkdir -p \$(dirname \"\$2\"); cp \"\$1\" \"$2\"\;" > ~/local/bin/cpmkdir; chmod +x ~/local/bin/cpmkdir

Je kunt het dan gebruiken als:

find -name files_you_re_lookin_for.* -exec cpmkdir {} ../extracted_copy/{} \;


Antwoord 25

Stel dat je iets doet als

cp bestand1.txt A/B/C/D/bestand.txt

waarbij A/B/C/D mappen zijn die nog niet bestaan

Een mogelijke oplossing is als volgt

DIR=$(dirname A/B/C/D/file.txt)
# DIR= "A/B/C/D"
mkdir -p $DIR
cp file1.txt A/B/C/D/file.txt

hoop dat dat helpt!


Antwoord 26

Eenvoudig

cp -a * /path/to/dst/

zou moeten lukken.

Other episodes