Copy specific file type keeping the folder structure

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
76
down vote

favorite
38












I have a folder structure with a bunch of *.csv files scattered across the folders. Now I want to copy all *.csv files to another destination keeping the folder structure.



It works by doing:



cp --parents *.csv /target
cp --parents */*.csv" /target
cp --parents */*/*.csv /target
cp --parents */*/*/*.csv /target
...


and so on, but I would like to do it using one command.







share|improve this question














migrated from serverfault.com Jul 19 '13 at 2:46


This question came from our site for system and network administrators.


















    up vote
    76
    down vote

    favorite
    38












    I have a folder structure with a bunch of *.csv files scattered across the folders. Now I want to copy all *.csv files to another destination keeping the folder structure.



    It works by doing:



    cp --parents *.csv /target
    cp --parents */*.csv" /target
    cp --parents */*/*.csv /target
    cp --parents */*/*/*.csv /target
    ...


    and so on, but I would like to do it using one command.







    share|improve this question














    migrated from serverfault.com Jul 19 '13 at 2:46


    This question came from our site for system and network administrators.
















      up vote
      76
      down vote

      favorite
      38









      up vote
      76
      down vote

      favorite
      38






      38





      I have a folder structure with a bunch of *.csv files scattered across the folders. Now I want to copy all *.csv files to another destination keeping the folder structure.



      It works by doing:



      cp --parents *.csv /target
      cp --parents */*.csv" /target
      cp --parents */*/*.csv /target
      cp --parents */*/*/*.csv /target
      ...


      and so on, but I would like to do it using one command.







      share|improve this question














      I have a folder structure with a bunch of *.csv files scattered across the folders. Now I want to copy all *.csv files to another destination keeping the folder structure.



      It works by doing:



      cp --parents *.csv /target
      cp --parents */*.csv" /target
      cp --parents */*/*.csv /target
      cp --parents */*/*/*.csv /target
      ...


      and so on, but I would like to do it using one command.









      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 18 '14 at 18:11









      Wilfred Hughes

      1034




      1034










      asked Jul 18 '13 at 13:39







      Mojo











      migrated from serverfault.com Jul 19 '13 at 2:46


      This question came from our site for system and network administrators.






      migrated from serverfault.com Jul 19 '13 at 2:46


      This question came from our site for system and network administrators.






















          7 Answers
          7






          active

          oldest

          votes

















          up vote
          87
          down vote













          Is there any reason why people resist using find's -exec? It's very handy.



          find . -name '*.csv' -exec cp --parents /target ;


          Know your tools. ;-)






          share|improve this answer


















          • 45




            Probably because of this ;
            – igo
            Mar 4 '15 at 13:56






          • 7




            '' works just as well
            – OrangeDog
            Dec 7 '15 at 17:44






          • 3




            Even though -execdir is safer than -exec, simply replacing one with the other does not preserve the folder structure as intended.
            – Simon Shine
            Aug 23 '16 at 11:33






          • 2




            Why I get message 'Omitting directory' when I try to copy them with your command ?
            – Vicky Dev
            Sep 6 '16 at 7:32






          • 2




            Can you explain why the braces have to be escaped here?
            – Noumenon
            Oct 23 '16 at 3:26

















          up vote
          32
          down vote













          You could also use rsync for this.



          $ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/


          If you want to keep empty directories from the source tree, skip the --prune-empty-dirs option:



          $ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/


          If you do not want symlinks, modification dates, file permissions, owners etc. preserved, please replace -a with another combination of -rlptgoD. ;-)






          share|improve this answer




















          • -m is a shortcut for --prune-emty-dirs.
            – Geremia
            Sep 24 '16 at 0:59










          • Also, the -R option can be added to copy the parent directory structure of source. (cf. my answer here.)
            – Geremia
            Sep 24 '16 at 1:52


















          up vote
          22
          down vote













          You can use find and cpio in pass through mode



          find . -name '*.csv' | cpio -pdm /target


          This will find all .csv files in the current directory and below and copy them to /target maintaining the directory structure rooted in ..



          If you use



          find /path/to/files -name '*.csv' | cpio -pdm /target


          it will find all of the file in /path/to/files and below and copy them to /target/path/to/files and below.






          share|improve this answer
















          • 2




            I tried all the answers top down up to this one, and this was the only one that worked on the first attempt
            – OscarRyz
            Jun 24 '16 at 19:10










          • Agree with @OscarRyz, works this is the only one which works on the first attempt
            – user1572215
            Apr 6 at 7:54











          • Simplest answer and worked for me on a mac
            – kezzos
            Jul 31 at 10:34

















          up vote
          15
          down vote













          The cp command permits multiple source arguments:



          cp **/*.csv --parents ../target


          CAVEAT: I'm using a recursive glob here; this is the globstar option in Bash 4+ and ksh, and is supported by default in zsh. Recursive globs do not match hidden files and folders, and the some implementations follow symlinks while others do not.



          If your shell doesn't support recursive globs, or if you'd prefer not to use them, you can do the following:




          • *.csv */*.csv */*/*.csv */*/*/*.csv -- this is of course very redundant and requires knowing how deep your directory structure is.


          • $(find . -name '*.csv') -- This will match hidden files and folders. find also supports specifying whether or not symlinks are followed, which may be useful.





          share|improve this answer






















          • this is exactly what i tried (the recursive glob) and it found some but not all? pretty weird. I got the same exact result when using the npm copyfiles script but if i use the find command it finds everything...
            – Randyaa
            Sep 2 '16 at 15:22










          • @Randyaa I'll need some more details on which files, exactly, weren't found in order to help you. You may find the discussion here and continued here about the precise behavior of the recursive glob useful.
            – Kyle Strand
            Sep 2 '16 at 15:50










          • turns out recursive glob wasn't enabled for some reason... I've never run into this before but i corrected it with just an execution of shopt -s globstar immediately before my command and all is well. Thanks for the follow up!
            – Randyaa
            Sep 2 '16 at 15:52










          • @Randyaa Ah, yeah, it's off by default, at least in Bash.
            – Kyle Strand
            Sep 2 '16 at 15:58











          • @Randyaa I've added some details about recursive globs; in particular, note that symlinks can introduce some complications.
            – Kyle Strand
            Sep 2 '16 at 17:12

















          up vote
          8
          down vote













          Assuming you want to replicate this structure from ./source to ./destination:



          cd source
          find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)


          I'm prepared to count that as one line, the cd source being a shell builtin.






          share|improve this answer
















          • 2




            I don't think he really means one command - just not having to fag about like his example ;)
            – Iain
            Jul 18 '13 at 15:04










          • tar has the -C option to avoid having to change the directory first.
            – bart
            Nov 4 '16 at 11:54

















          up vote
          7
          down vote













          This one worked for me:



          find -name "*.csv" | xargs cp --parents -t /target






          share|improve this answer



























            up vote
            6
            down vote













            From rsync's manpage:




            -R, --relative



            Use relative paths. This means that the full path names specified on
            the command line are sent to the server rather than just the last
            parts of the filenames. This is particularly useful when you want to
            send several different directories at the same time. For example, if
            you used this command:



            rsync -av /foo/bar/baz.c remote:/tmp/


            ... this would create a file named baz.c in /tmp/ on the remote
            machine. If instead you used



            rsync -avR /foo/bar/baz.c remote:/tmp/


            then a file named /tmp/foo/bar/baz.c would be created on the remote
            machine, preserving its full path. These extra path elements are
            called "implied directories" (i.e. the "foo" and the "foo/bar"
            directories in the above example).




            So, this would work, too:



            rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/





            share|improve this answer






















              Your Answer







              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "106"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f83593%2fcopy-specific-file-type-keeping-the-folder-structure%23new-answer', 'question_page');

              );

              Post as a guest





























              7 Answers
              7






              active

              oldest

              votes








              7 Answers
              7






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              87
              down vote













              Is there any reason why people resist using find's -exec? It's very handy.



              find . -name '*.csv' -exec cp --parents /target ;


              Know your tools. ;-)






              share|improve this answer


















              • 45




                Probably because of this ;
                – igo
                Mar 4 '15 at 13:56






              • 7




                '' works just as well
                – OrangeDog
                Dec 7 '15 at 17:44






              • 3




                Even though -execdir is safer than -exec, simply replacing one with the other does not preserve the folder structure as intended.
                – Simon Shine
                Aug 23 '16 at 11:33






              • 2




                Why I get message 'Omitting directory' when I try to copy them with your command ?
                – Vicky Dev
                Sep 6 '16 at 7:32






              • 2




                Can you explain why the braces have to be escaped here?
                – Noumenon
                Oct 23 '16 at 3:26














              up vote
              87
              down vote













              Is there any reason why people resist using find's -exec? It's very handy.



              find . -name '*.csv' -exec cp --parents /target ;


              Know your tools. ;-)






              share|improve this answer


















              • 45




                Probably because of this ;
                – igo
                Mar 4 '15 at 13:56






              • 7




                '' works just as well
                – OrangeDog
                Dec 7 '15 at 17:44






              • 3




                Even though -execdir is safer than -exec, simply replacing one with the other does not preserve the folder structure as intended.
                – Simon Shine
                Aug 23 '16 at 11:33






              • 2




                Why I get message 'Omitting directory' when I try to copy them with your command ?
                – Vicky Dev
                Sep 6 '16 at 7:32






              • 2




                Can you explain why the braces have to be escaped here?
                – Noumenon
                Oct 23 '16 at 3:26












              up vote
              87
              down vote










              up vote
              87
              down vote









              Is there any reason why people resist using find's -exec? It's very handy.



              find . -name '*.csv' -exec cp --parents /target ;


              Know your tools. ;-)






              share|improve this answer














              Is there any reason why people resist using find's -exec? It's very handy.



              find . -name '*.csv' -exec cp --parents /target ;


              Know your tools. ;-)







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Oct 11 '14 at 0:39

























              answered Jan 3 '14 at 8:39









              msb

              1,04579




              1,04579







              • 45




                Probably because of this ;
                – igo
                Mar 4 '15 at 13:56






              • 7




                '' works just as well
                – OrangeDog
                Dec 7 '15 at 17:44






              • 3




                Even though -execdir is safer than -exec, simply replacing one with the other does not preserve the folder structure as intended.
                – Simon Shine
                Aug 23 '16 at 11:33






              • 2




                Why I get message 'Omitting directory' when I try to copy them with your command ?
                – Vicky Dev
                Sep 6 '16 at 7:32






              • 2




                Can you explain why the braces have to be escaped here?
                – Noumenon
                Oct 23 '16 at 3:26












              • 45




                Probably because of this ;
                – igo
                Mar 4 '15 at 13:56






              • 7




                '' works just as well
                – OrangeDog
                Dec 7 '15 at 17:44






              • 3




                Even though -execdir is safer than -exec, simply replacing one with the other does not preserve the folder structure as intended.
                – Simon Shine
                Aug 23 '16 at 11:33






              • 2




                Why I get message 'Omitting directory' when I try to copy them with your command ?
                – Vicky Dev
                Sep 6 '16 at 7:32






              • 2




                Can you explain why the braces have to be escaped here?
                – Noumenon
                Oct 23 '16 at 3:26







              45




              45




              Probably because of this ;
              – igo
              Mar 4 '15 at 13:56




              Probably because of this ;
              – igo
              Mar 4 '15 at 13:56




              7




              7




              '' works just as well
              – OrangeDog
              Dec 7 '15 at 17:44




              '' works just as well
              – OrangeDog
              Dec 7 '15 at 17:44




              3




              3




              Even though -execdir is safer than -exec, simply replacing one with the other does not preserve the folder structure as intended.
              – Simon Shine
              Aug 23 '16 at 11:33




              Even though -execdir is safer than -exec, simply replacing one with the other does not preserve the folder structure as intended.
              – Simon Shine
              Aug 23 '16 at 11:33




              2




              2




              Why I get message 'Omitting directory' when I try to copy them with your command ?
              – Vicky Dev
              Sep 6 '16 at 7:32




              Why I get message 'Omitting directory' when I try to copy them with your command ?
              – Vicky Dev
              Sep 6 '16 at 7:32




              2




              2




              Can you explain why the braces have to be escaped here?
              – Noumenon
              Oct 23 '16 at 3:26




              Can you explain why the braces have to be escaped here?
              – Noumenon
              Oct 23 '16 at 3:26












              up vote
              32
              down vote













              You could also use rsync for this.



              $ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you want to keep empty directories from the source tree, skip the --prune-empty-dirs option:



              $ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you do not want symlinks, modification dates, file permissions, owners etc. preserved, please replace -a with another combination of -rlptgoD. ;-)






              share|improve this answer




















              • -m is a shortcut for --prune-emty-dirs.
                – Geremia
                Sep 24 '16 at 0:59










              • Also, the -R option can be added to copy the parent directory structure of source. (cf. my answer here.)
                – Geremia
                Sep 24 '16 at 1:52















              up vote
              32
              down vote













              You could also use rsync for this.



              $ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you want to keep empty directories from the source tree, skip the --prune-empty-dirs option:



              $ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you do not want symlinks, modification dates, file permissions, owners etc. preserved, please replace -a with another combination of -rlptgoD. ;-)






              share|improve this answer




















              • -m is a shortcut for --prune-emty-dirs.
                – Geremia
                Sep 24 '16 at 0:59










              • Also, the -R option can be added to copy the parent directory structure of source. (cf. my answer here.)
                – Geremia
                Sep 24 '16 at 1:52













              up vote
              32
              down vote










              up vote
              32
              down vote









              You could also use rsync for this.



              $ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you want to keep empty directories from the source tree, skip the --prune-empty-dirs option:



              $ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you do not want symlinks, modification dates, file permissions, owners etc. preserved, please replace -a with another combination of -rlptgoD. ;-)






              share|improve this answer












              You could also use rsync for this.



              $ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you want to keep empty directories from the source tree, skip the --prune-empty-dirs option:



              $ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/


              If you do not want symlinks, modification dates, file permissions, owners etc. preserved, please replace -a with another combination of -rlptgoD. ;-)







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jul 18 '13 at 15:37









              Dubu

              2,2961022




              2,2961022











              • -m is a shortcut for --prune-emty-dirs.
                – Geremia
                Sep 24 '16 at 0:59










              • Also, the -R option can be added to copy the parent directory structure of source. (cf. my answer here.)
                – Geremia
                Sep 24 '16 at 1:52

















              • -m is a shortcut for --prune-emty-dirs.
                – Geremia
                Sep 24 '16 at 0:59










              • Also, the -R option can be added to copy the parent directory structure of source. (cf. my answer here.)
                – Geremia
                Sep 24 '16 at 1:52
















              -m is a shortcut for --prune-emty-dirs.
              – Geremia
              Sep 24 '16 at 0:59




              -m is a shortcut for --prune-emty-dirs.
              – Geremia
              Sep 24 '16 at 0:59












              Also, the -R option can be added to copy the parent directory structure of source. (cf. my answer here.)
              – Geremia
              Sep 24 '16 at 1:52





              Also, the -R option can be added to copy the parent directory structure of source. (cf. my answer here.)
              – Geremia
              Sep 24 '16 at 1:52











              up vote
              22
              down vote













              You can use find and cpio in pass through mode



              find . -name '*.csv' | cpio -pdm /target


              This will find all .csv files in the current directory and below and copy them to /target maintaining the directory structure rooted in ..



              If you use



              find /path/to/files -name '*.csv' | cpio -pdm /target


              it will find all of the file in /path/to/files and below and copy them to /target/path/to/files and below.






              share|improve this answer
















              • 2




                I tried all the answers top down up to this one, and this was the only one that worked on the first attempt
                – OscarRyz
                Jun 24 '16 at 19:10










              • Agree with @OscarRyz, works this is the only one which works on the first attempt
                – user1572215
                Apr 6 at 7:54











              • Simplest answer and worked for me on a mac
                – kezzos
                Jul 31 at 10:34














              up vote
              22
              down vote













              You can use find and cpio in pass through mode



              find . -name '*.csv' | cpio -pdm /target


              This will find all .csv files in the current directory and below and copy them to /target maintaining the directory structure rooted in ..



              If you use



              find /path/to/files -name '*.csv' | cpio -pdm /target


              it will find all of the file in /path/to/files and below and copy them to /target/path/to/files and below.






              share|improve this answer
















              • 2




                I tried all the answers top down up to this one, and this was the only one that worked on the first attempt
                – OscarRyz
                Jun 24 '16 at 19:10










              • Agree with @OscarRyz, works this is the only one which works on the first attempt
                – user1572215
                Apr 6 at 7:54











              • Simplest answer and worked for me on a mac
                – kezzos
                Jul 31 at 10:34












              up vote
              22
              down vote










              up vote
              22
              down vote









              You can use find and cpio in pass through mode



              find . -name '*.csv' | cpio -pdm /target


              This will find all .csv files in the current directory and below and copy them to /target maintaining the directory structure rooted in ..



              If you use



              find /path/to/files -name '*.csv' | cpio -pdm /target


              it will find all of the file in /path/to/files and below and copy them to /target/path/to/files and below.






              share|improve this answer












              You can use find and cpio in pass through mode



              find . -name '*.csv' | cpio -pdm /target


              This will find all .csv files in the current directory and below and copy them to /target maintaining the directory structure rooted in ..



              If you use



              find /path/to/files -name '*.csv' | cpio -pdm /target


              it will find all of the file in /path/to/files and below and copy them to /target/path/to/files and below.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jul 18 '13 at 14:58









              Iain

              4,29411426




              4,29411426







              • 2




                I tried all the answers top down up to this one, and this was the only one that worked on the first attempt
                – OscarRyz
                Jun 24 '16 at 19:10










              • Agree with @OscarRyz, works this is the only one which works on the first attempt
                – user1572215
                Apr 6 at 7:54











              • Simplest answer and worked for me on a mac
                – kezzos
                Jul 31 at 10:34












              • 2




                I tried all the answers top down up to this one, and this was the only one that worked on the first attempt
                – OscarRyz
                Jun 24 '16 at 19:10










              • Agree with @OscarRyz, works this is the only one which works on the first attempt
                – user1572215
                Apr 6 at 7:54











              • Simplest answer and worked for me on a mac
                – kezzos
                Jul 31 at 10:34







              2




              2




              I tried all the answers top down up to this one, and this was the only one that worked on the first attempt
              – OscarRyz
              Jun 24 '16 at 19:10




              I tried all the answers top down up to this one, and this was the only one that worked on the first attempt
              – OscarRyz
              Jun 24 '16 at 19:10












              Agree with @OscarRyz, works this is the only one which works on the first attempt
              – user1572215
              Apr 6 at 7:54





              Agree with @OscarRyz, works this is the only one which works on the first attempt
              – user1572215
              Apr 6 at 7:54













              Simplest answer and worked for me on a mac
              – kezzos
              Jul 31 at 10:34




              Simplest answer and worked for me on a mac
              – kezzos
              Jul 31 at 10:34










              up vote
              15
              down vote













              The cp command permits multiple source arguments:



              cp **/*.csv --parents ../target


              CAVEAT: I'm using a recursive glob here; this is the globstar option in Bash 4+ and ksh, and is supported by default in zsh. Recursive globs do not match hidden files and folders, and the some implementations follow symlinks while others do not.



              If your shell doesn't support recursive globs, or if you'd prefer not to use them, you can do the following:




              • *.csv */*.csv */*/*.csv */*/*/*.csv -- this is of course very redundant and requires knowing how deep your directory structure is.


              • $(find . -name '*.csv') -- This will match hidden files and folders. find also supports specifying whether or not symlinks are followed, which may be useful.





              share|improve this answer






















              • this is exactly what i tried (the recursive glob) and it found some but not all? pretty weird. I got the same exact result when using the npm copyfiles script but if i use the find command it finds everything...
                – Randyaa
                Sep 2 '16 at 15:22










              • @Randyaa I'll need some more details on which files, exactly, weren't found in order to help you. You may find the discussion here and continued here about the precise behavior of the recursive glob useful.
                – Kyle Strand
                Sep 2 '16 at 15:50










              • turns out recursive glob wasn't enabled for some reason... I've never run into this before but i corrected it with just an execution of shopt -s globstar immediately before my command and all is well. Thanks for the follow up!
                – Randyaa
                Sep 2 '16 at 15:52










              • @Randyaa Ah, yeah, it's off by default, at least in Bash.
                – Kyle Strand
                Sep 2 '16 at 15:58











              • @Randyaa I've added some details about recursive globs; in particular, note that symlinks can introduce some complications.
                – Kyle Strand
                Sep 2 '16 at 17:12














              up vote
              15
              down vote













              The cp command permits multiple source arguments:



              cp **/*.csv --parents ../target


              CAVEAT: I'm using a recursive glob here; this is the globstar option in Bash 4+ and ksh, and is supported by default in zsh. Recursive globs do not match hidden files and folders, and the some implementations follow symlinks while others do not.



              If your shell doesn't support recursive globs, or if you'd prefer not to use them, you can do the following:




              • *.csv */*.csv */*/*.csv */*/*/*.csv -- this is of course very redundant and requires knowing how deep your directory structure is.


              • $(find . -name '*.csv') -- This will match hidden files and folders. find also supports specifying whether or not symlinks are followed, which may be useful.





              share|improve this answer






















              • this is exactly what i tried (the recursive glob) and it found some but not all? pretty weird. I got the same exact result when using the npm copyfiles script but if i use the find command it finds everything...
                – Randyaa
                Sep 2 '16 at 15:22










              • @Randyaa I'll need some more details on which files, exactly, weren't found in order to help you. You may find the discussion here and continued here about the precise behavior of the recursive glob useful.
                – Kyle Strand
                Sep 2 '16 at 15:50










              • turns out recursive glob wasn't enabled for some reason... I've never run into this before but i corrected it with just an execution of shopt -s globstar immediately before my command and all is well. Thanks for the follow up!
                – Randyaa
                Sep 2 '16 at 15:52










              • @Randyaa Ah, yeah, it's off by default, at least in Bash.
                – Kyle Strand
                Sep 2 '16 at 15:58











              • @Randyaa I've added some details about recursive globs; in particular, note that symlinks can introduce some complications.
                – Kyle Strand
                Sep 2 '16 at 17:12












              up vote
              15
              down vote










              up vote
              15
              down vote









              The cp command permits multiple source arguments:



              cp **/*.csv --parents ../target


              CAVEAT: I'm using a recursive glob here; this is the globstar option in Bash 4+ and ksh, and is supported by default in zsh. Recursive globs do not match hidden files and folders, and the some implementations follow symlinks while others do not.



              If your shell doesn't support recursive globs, or if you'd prefer not to use them, you can do the following:




              • *.csv */*.csv */*/*.csv */*/*/*.csv -- this is of course very redundant and requires knowing how deep your directory structure is.


              • $(find . -name '*.csv') -- This will match hidden files and folders. find also supports specifying whether or not symlinks are followed, which may be useful.





              share|improve this answer














              The cp command permits multiple source arguments:



              cp **/*.csv --parents ../target


              CAVEAT: I'm using a recursive glob here; this is the globstar option in Bash 4+ and ksh, and is supported by default in zsh. Recursive globs do not match hidden files and folders, and the some implementations follow symlinks while others do not.



              If your shell doesn't support recursive globs, or if you'd prefer not to use them, you can do the following:




              • *.csv */*.csv */*/*.csv */*/*/*.csv -- this is of course very redundant and requires knowing how deep your directory structure is.


              • $(find . -name '*.csv') -- This will match hidden files and folders. find also supports specifying whether or not symlinks are followed, which may be useful.






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 13 '17 at 12:36









              Community♦

              1




              1










              answered May 29 '14 at 19:37









              Kyle Strand

              334211




              334211











              • this is exactly what i tried (the recursive glob) and it found some but not all? pretty weird. I got the same exact result when using the npm copyfiles script but if i use the find command it finds everything...
                – Randyaa
                Sep 2 '16 at 15:22










              • @Randyaa I'll need some more details on which files, exactly, weren't found in order to help you. You may find the discussion here and continued here about the precise behavior of the recursive glob useful.
                – Kyle Strand
                Sep 2 '16 at 15:50










              • turns out recursive glob wasn't enabled for some reason... I've never run into this before but i corrected it with just an execution of shopt -s globstar immediately before my command and all is well. Thanks for the follow up!
                – Randyaa
                Sep 2 '16 at 15:52










              • @Randyaa Ah, yeah, it's off by default, at least in Bash.
                – Kyle Strand
                Sep 2 '16 at 15:58











              • @Randyaa I've added some details about recursive globs; in particular, note that symlinks can introduce some complications.
                – Kyle Strand
                Sep 2 '16 at 17:12
















              • this is exactly what i tried (the recursive glob) and it found some but not all? pretty weird. I got the same exact result when using the npm copyfiles script but if i use the find command it finds everything...
                – Randyaa
                Sep 2 '16 at 15:22










              • @Randyaa I'll need some more details on which files, exactly, weren't found in order to help you. You may find the discussion here and continued here about the precise behavior of the recursive glob useful.
                – Kyle Strand
                Sep 2 '16 at 15:50










              • turns out recursive glob wasn't enabled for some reason... I've never run into this before but i corrected it with just an execution of shopt -s globstar immediately before my command and all is well. Thanks for the follow up!
                – Randyaa
                Sep 2 '16 at 15:52










              • @Randyaa Ah, yeah, it's off by default, at least in Bash.
                – Kyle Strand
                Sep 2 '16 at 15:58











              • @Randyaa I've added some details about recursive globs; in particular, note that symlinks can introduce some complications.
                – Kyle Strand
                Sep 2 '16 at 17:12















              this is exactly what i tried (the recursive glob) and it found some but not all? pretty weird. I got the same exact result when using the npm copyfiles script but if i use the find command it finds everything...
              – Randyaa
              Sep 2 '16 at 15:22




              this is exactly what i tried (the recursive glob) and it found some but not all? pretty weird. I got the same exact result when using the npm copyfiles script but if i use the find command it finds everything...
              – Randyaa
              Sep 2 '16 at 15:22












              @Randyaa I'll need some more details on which files, exactly, weren't found in order to help you. You may find the discussion here and continued here about the precise behavior of the recursive glob useful.
              – Kyle Strand
              Sep 2 '16 at 15:50




              @Randyaa I'll need some more details on which files, exactly, weren't found in order to help you. You may find the discussion here and continued here about the precise behavior of the recursive glob useful.
              – Kyle Strand
              Sep 2 '16 at 15:50












              turns out recursive glob wasn't enabled for some reason... I've never run into this before but i corrected it with just an execution of shopt -s globstar immediately before my command and all is well. Thanks for the follow up!
              – Randyaa
              Sep 2 '16 at 15:52




              turns out recursive glob wasn't enabled for some reason... I've never run into this before but i corrected it with just an execution of shopt -s globstar immediately before my command and all is well. Thanks for the follow up!
              – Randyaa
              Sep 2 '16 at 15:52












              @Randyaa Ah, yeah, it's off by default, at least in Bash.
              – Kyle Strand
              Sep 2 '16 at 15:58





              @Randyaa Ah, yeah, it's off by default, at least in Bash.
              – Kyle Strand
              Sep 2 '16 at 15:58













              @Randyaa I've added some details about recursive globs; in particular, note that symlinks can introduce some complications.
              – Kyle Strand
              Sep 2 '16 at 17:12




              @Randyaa I've added some details about recursive globs; in particular, note that symlinks can introduce some complications.
              – Kyle Strand
              Sep 2 '16 at 17:12










              up vote
              8
              down vote













              Assuming you want to replicate this structure from ./source to ./destination:



              cd source
              find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)


              I'm prepared to count that as one line, the cd source being a shell builtin.






              share|improve this answer
















              • 2




                I don't think he really means one command - just not having to fag about like his example ;)
                – Iain
                Jul 18 '13 at 15:04










              • tar has the -C option to avoid having to change the directory first.
                – bart
                Nov 4 '16 at 11:54














              up vote
              8
              down vote













              Assuming you want to replicate this structure from ./source to ./destination:



              cd source
              find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)


              I'm prepared to count that as one line, the cd source being a shell builtin.






              share|improve this answer
















              • 2




                I don't think he really means one command - just not having to fag about like his example ;)
                – Iain
                Jul 18 '13 at 15:04










              • tar has the -C option to avoid having to change the directory first.
                – bart
                Nov 4 '16 at 11:54












              up vote
              8
              down vote










              up vote
              8
              down vote









              Assuming you want to replicate this structure from ./source to ./destination:



              cd source
              find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)


              I'm prepared to count that as one line, the cd source being a shell builtin.






              share|improve this answer












              Assuming you want to replicate this structure from ./source to ./destination:



              cd source
              find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)


              I'm prepared to count that as one line, the cd source being a shell builtin.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jul 18 '13 at 14:26









              MadHatter

              60647




              60647







              • 2




                I don't think he really means one command - just not having to fag about like his example ;)
                – Iain
                Jul 18 '13 at 15:04










              • tar has the -C option to avoid having to change the directory first.
                – bart
                Nov 4 '16 at 11:54












              • 2




                I don't think he really means one command - just not having to fag about like his example ;)
                – Iain
                Jul 18 '13 at 15:04










              • tar has the -C option to avoid having to change the directory first.
                – bart
                Nov 4 '16 at 11:54







              2




              2




              I don't think he really means one command - just not having to fag about like his example ;)
              – Iain
              Jul 18 '13 at 15:04




              I don't think he really means one command - just not having to fag about like his example ;)
              – Iain
              Jul 18 '13 at 15:04












              tar has the -C option to avoid having to change the directory first.
              – bart
              Nov 4 '16 at 11:54




              tar has the -C option to avoid having to change the directory first.
              – bart
              Nov 4 '16 at 11:54










              up vote
              7
              down vote













              This one worked for me:



              find -name "*.csv" | xargs cp --parents -t /target






              share|improve this answer
























                up vote
                7
                down vote













                This one worked for me:



                find -name "*.csv" | xargs cp --parents -t /target






                share|improve this answer






















                  up vote
                  7
                  down vote










                  up vote
                  7
                  down vote









                  This one worked for me:



                  find -name "*.csv" | xargs cp --parents -t /target






                  share|improve this answer












                  This one worked for me:



                  find -name "*.csv" | xargs cp --parents -t /target







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Oct 6 '16 at 20:23









                  marko

                  7111




                  7111




















                      up vote
                      6
                      down vote













                      From rsync's manpage:




                      -R, --relative



                      Use relative paths. This means that the full path names specified on
                      the command line are sent to the server rather than just the last
                      parts of the filenames. This is particularly useful when you want to
                      send several different directories at the same time. For example, if
                      you used this command:



                      rsync -av /foo/bar/baz.c remote:/tmp/


                      ... this would create a file named baz.c in /tmp/ on the remote
                      machine. If instead you used



                      rsync -avR /foo/bar/baz.c remote:/tmp/


                      then a file named /tmp/foo/bar/baz.c would be created on the remote
                      machine, preserving its full path. These extra path elements are
                      called "implied directories" (i.e. the "foo" and the "foo/bar"
                      directories in the above example).




                      So, this would work, too:



                      rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/





                      share|improve this answer


























                        up vote
                        6
                        down vote













                        From rsync's manpage:




                        -R, --relative



                        Use relative paths. This means that the full path names specified on
                        the command line are sent to the server rather than just the last
                        parts of the filenames. This is particularly useful when you want to
                        send several different directories at the same time. For example, if
                        you used this command:



                        rsync -av /foo/bar/baz.c remote:/tmp/


                        ... this would create a file named baz.c in /tmp/ on the remote
                        machine. If instead you used



                        rsync -avR /foo/bar/baz.c remote:/tmp/


                        then a file named /tmp/foo/bar/baz.c would be created on the remote
                        machine, preserving its full path. These extra path elements are
                        called "implied directories" (i.e. the "foo" and the "foo/bar"
                        directories in the above example).




                        So, this would work, too:



                        rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/





                        share|improve this answer
























                          up vote
                          6
                          down vote










                          up vote
                          6
                          down vote









                          From rsync's manpage:




                          -R, --relative



                          Use relative paths. This means that the full path names specified on
                          the command line are sent to the server rather than just the last
                          parts of the filenames. This is particularly useful when you want to
                          send several different directories at the same time. For example, if
                          you used this command:



                          rsync -av /foo/bar/baz.c remote:/tmp/


                          ... this would create a file named baz.c in /tmp/ on the remote
                          machine. If instead you used



                          rsync -avR /foo/bar/baz.c remote:/tmp/


                          then a file named /tmp/foo/bar/baz.c would be created on the remote
                          machine, preserving its full path. These extra path elements are
                          called "implied directories" (i.e. the "foo" and the "foo/bar"
                          directories in the above example).




                          So, this would work, too:



                          rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/





                          share|improve this answer














                          From rsync's manpage:




                          -R, --relative



                          Use relative paths. This means that the full path names specified on
                          the command line are sent to the server rather than just the last
                          parts of the filenames. This is particularly useful when you want to
                          send several different directories at the same time. For example, if
                          you used this command:



                          rsync -av /foo/bar/baz.c remote:/tmp/


                          ... this would create a file named baz.c in /tmp/ on the remote
                          machine. If instead you used



                          rsync -avR /foo/bar/baz.c remote:/tmp/


                          then a file named /tmp/foo/bar/baz.c would be created on the remote
                          machine, preserving its full path. These extra path elements are
                          called "implied directories" (i.e. the "foo" and the "foo/bar"
                          directories in the above example).




                          So, this would work, too:



                          rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Sep 24 '16 at 1:56

























                          answered Sep 24 '16 at 0:37









                          Geremia

                          519716




                          519716






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f83593%2fcopy-specific-file-type-keeping-the-folder-structure%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              Peggy Mitchell

                              Palaiologos

                              The Forum (Inglewood, California)