LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Server
User Name
Password
Linux - Server This forum is for the discussion of Linux Software used in a server related context.

Notices


Reply
  Search this Thread
Old 06-29-2015, 01:25 AM   #1
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311
Blog Entries: 2

Rep: Reputation: 16
Question Can't preserve directory structure when copying files


Copying files of certain type while preserving directory structure

I would like to copy all *.man files from /home/a/Manfiles to /home/a/Documents/Manfiles. The source directory /home/a/Manfiles has some *.man files in it, and it also has subdirectories, each having at least one *.man file in them.

Attempt 01:
I decide to use the 'cp' command with the '-r' option, as to not only copy over '/home/a/Manfiles' but also all of it's subdirectories and the '*.man' files they contain.
Code:
$ cp -pr --parents /home/a/Manfiles/*.man /home/a/Documents/Manfiles
but I get the results:
Code:
$ cp -pr --parents /home/a/Manfiles/*.man /home/a/Documents/Manfiles
cp: target /home/a/Documents/Manfiles is not a directory
Even if I first run 'mkdir /home/a/Documents/Manfiles', still there is no 'recursive' effect at all; No subdirectories(e.g. Manfiles/1, Manfiles/1/2) nor the '*.man' files they contain were copied.

Attempt 02:
Code:
find /home/a/Manfiles/ -type f -name '*.man' | cpio -p -dumv /home/a/Documents/Manfiles
This is the closest to being correct, especially since I didn't have to first create the directory structure before running this command (like in attempt 01). Unfortunately, it copies the entire directory structure, rather than just the recursive directory structure. What do I mean by this? I mean that my goal is to copy the directory structure AFTER(/to the right) of "Manfiles". I don't want directory structure BEFORE(/to the left, e.g. /home/a/). For example, I would like to achieve the target directory structure of /home/a/Documents/Manfiles/1/2, but what I really get is /home/a/Documents/Manfiles/home/a/Manfiles/1/2. Notice how the "/home/a" before "Documents" is a duplicate of the "home/a" between the "Manfiles". The two "Manfiles" are also duplicates.

Attempt 03:
Code:
find /home/a/Manfiles -name '*.man' -exec cp -rat /home/a/Documents/Manfiles {} +
This fails with the following output:
Code:
a@a-NC210-NC110:/home/a$ find /home/a/Manfiles/ -name '*.man' -exec cp -rat /home/a/Documents/Manfiles {} +
cp: failed to access /home/a/Documents/Manfiles: No such file or directory
Moreover, even as with attempt 01 and I first 'mkdir /home/a/Documents/Manfiles', this merely just copies all the *.man files from all directories within /home/a/Manfiles/ into the directory "/home/a/Documents/Manfiles", without preserving the directory structure(no subdirectories, e.g. Manfiles/1/2). This clearly isn't my goal.

Last edited by andrew.comly; 06-29-2015 at 07:46 AM. Reason: 'First try' explained incorrectly, directories written incorrectly
 
Old 06-29-2015, 02:15 AM   #2
veerain
Senior Member
 
Registered: Mar 2005
Location: Earth bound to Helios
Distribution: Custom
Posts: 2,524

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
Check whether this directory '/home/a/Documents/Manfiles' still exists and then

Try this:
Code:
cp -dpr /home/a/Manfiles/*.man /home/a/Documents/Manfiles
 
Old 06-29-2015, 07:16 AM   #3
fatmac
LQ Guru
 
Registered: Sep 2011
Location: Upper Hale, Surrey/Hants Border, UK
Distribution: Mainly Devuan, antiX, & Void, with Tiny Core, Fatdog, & BSD thrown in.
Posts: 5,491

Rep: Reputation: Disabled
Possibly,
Code:
cp -a /home/a/Manfiles /home/a/Documents

Last edited by fatmac; 06-29-2015 at 07:17 AM.
 
1 members found this post helpful.
Old 06-29-2015, 07:36 AM   #4
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Same result as Attempt 01

Quote:
Originally Posted by veerain View Post
Check whether this directory '/home/a/Documents/Manfiles' still exists and then

Try this:
Code:
cp -dpr /home/a/Manfiles/*.man /home/a/Documents/Manfiles
Veera,
I apologize for not explaining my situation better. Thanks for the help, but this produces nearly the same result as Attempt 01. I need a command that can recursively copy both a target directory and it's subdirectories that initially don't exist.

---------- Post added 06-29-15 at 08:37 PM ----------

Everyone,
Does anyone know of a way of producing the same result as Attempt 02: 'find /home/a/Manfiles/ -type f -name '*.man' | cpio -p -dumv /home/a/Documents/Manfiles', but without the duplicate directory problem(described in Attempt 02)?
 
Old 06-29-2015, 07:58 AM   #5
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Thumbs down No

Quote:
Originally Posted by fatmac View Post
Code:
cp -a /home/a/Manfiles /home/a/Documents
fatmac,
this copies everything, not just the *.man files. I just want to copy the directory structure (except any directories that don't have *.man files) and the *.man files.
 
Old 06-29-2015, 08:34 AM   #6
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
A possible use for this is the new android 4.4 standard video output '*.3gp'. Many new smartphones have 13 Mega-pixel cameras. Many of you think that 13 Mega-pixel is quite alot. Actually this is the lowest possible resolution necessary to shoot certain crucial code that is shortly displayed on a video screen during many extra help sessions where the TA explains how to make certain programs. Does the TA want to go slowly? No, he/she wants to go quickly so he/she can get to the people waiting in line for help BEHIND YOU.

Nine and a half minutes of video notes (recording) takes up an unbelievable 1.1 GB!! Thus there is a need to move all *.3gp files from a built in hard-drive (especially with a netbook that only has a SSD!) and onto a portable backup hard drive.

Of course, if you do this you MUST know which extra help session this came from, which most people would use directories named for the topic covered. It wouldn't make sense to name the video notes 3gp file and put them all into one directory since along with that 3gp file there are quite a few programs you wrote trying to emulate the TA's success, not to mention each topic being located in a certain chapter (subdirectories).

Hence preserving directory/subdirectory structure IS ESSENTIAL. In case anyone wants to know why I want to know something so exacting, then I hope this application can help cure your boredom.
 
Old 06-29-2015, 10:47 AM   #7
veerain
Senior Member
 
Registered: Mar 2005
Location: Earth bound to Helios
Distribution: Custom
Posts: 2,524

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
Try this:

Code:
export dest_dir="/home/a/Documents/Manfiles"
mkdir -p "${dest_dir}"

export base_var="/home/a/Manfiles/"

find "${base_var}" -mindepth 1 -name "*\.man"
 | while read var1; do
     base_dir="`dirname "${var1#${base_var}}"`"
     mkdir -p "${dest_dir}/${base_dir}"
     cp -dp "${var1}" "${dest_dir}/${base_dir}"
    done
 
1 members found this post helpful.
Old 07-10-2015, 09:32 PM   #8
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Smile Thanks

veerain,
Thanks for your reply. But I am a bit behind on learning bash, and with your response I have started to dedicate two hours a day learning this. This way I will be able to understand your method more clearly, but I won't be able to try it out until at least 2 weeks later.

Thanks again!
 
Old 07-11-2015, 04:39 AM   #9
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Quote:
Originally Posted by andrew.comly View Post
Attempt 02:
Code:
find /home/a/Manfiles/ -type f -name '*.man' | cpio -p -dumv /home/a/Documents/Manfiles
This is the closest to being correct, especially since I didn't have to first create the directory structure before running this command (like in attempt 01). Unfortunately, it copies the entire directory structure, rather than just the recursive directory structure. What do I mean by this? I mean that my goal is to copy the directory structure AFTER(/to the right) of "Manfiles". I don't want directory structure BEFORE(/to the left, e.g. /home/a/).
...then you 'cd' into that directory first as that "anchors" your 'find'? With 'cpio':
Code:
cd /home/a/Manfiles && find . -type d -name "*.man" | cpio -pdm /home/a/Documents/Manfiles
or 'install':
Code:
cd /home/a/Manfiles && find . -type d -name "*.man" -print0 | xargs -0 -iX install -d /home/a/Documents/Manfiles/'X'
 
1 members found this post helpful.
Old 07-22-2015, 09:55 PM   #10
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Smile var1?

Veerain,
Again, I am still working on learning bash, have just grasped the two concepts of variables and exporting variables. From a previous C prog course I am familiar with "do .. while" conditions, but I still have the following question:

Quote:
Originally Posted by veerain View Post
...
Code:
 | while read var1; do
     base_dir="`dirname "${var1#${base_var}}"`"
     mkdir -p "${dest_dir}/${base_dir}"
     cp -dp "${var1}" "${dest_dir}/${base_dir}"
    done
May I ask what "var1" is? Is it a third variable?
 
Old 12-14-2015, 08:01 PM   #11
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Smile

I have accomplished what I was trying to do with rsync --prune-empty-dirs
Code:
$ LOCAL=media/a/LG/3gp
$ REMOTE=media/a/Sea_ext4/recent
rsync -Sai -Eu --stats --prune-empty-dirs -f "+ */" -f "+ *.3gp" -f "- *" /${REMOTE}/AC/Learn/Programming/C* /${LOCAL}
This really does exactly what I want. It first includes directories(or else it couldn't find target file types in subdirectories) with:
Code:
 -f "+ */"
-f stands for "filter rule", "+" at the beginning means "include", and "*/" means directory.

The second section of code
Code:
-f "+ *.3gp"
means include any file with name ending in 3gp.

The 3rd section of code
Code:
-f "- *"
means exclude any/every file. "-" means exclude. Naturally the wildcard "*" means any/every file.

Last edited by andrew.comly; 12-27-2015 at 08:47 AM. Reason: typo
 
  


Reply

Tags
bash, copy, directory, recursive, structure



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to preserve all timestamps while copying files megalosaurus Red Hat 12 07-13-2015 05:19 AM
Problem in copying directory structure agogoaye Linux - Newbie 9 07-02-2008 04:44 AM
Help - My Samba share changes the timestamp when copying files to it.. Preserve Time. hheejj Linux - Software 2 06-28-2005 09:34 AM
copying directory structure in FTP malaka56 Linux - Software 2 05-14-2005 07:04 PM
preserve user/group when copying files km4hr Linux - Software 1 01-11-2005 05:21 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Server

All times are GMT -5. The time now is 08:12 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration