[SOLVED] Copy list of files from text file and retain directory structure?
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I guess there is no simple solution for what i am looking for.
Sure there is - first you need to fix your text file to only contain the absolute file paths you want (i.e. no directories, no "package diverts others to: /usr/bin/firefox.real", etc).
Something like (there's probably a simpler way than this, and you'll want to verify it does the right thing):
Code:
dpkg -L firefox-esr | while IFS= read -r line; do test -f "$line" && echo "$line" >> ~/firefox-files.txt || echo "$line" >> ~/firefox-skipped.txt ;done
(UPDATE: ignore the rest and use the cleaner version crts wrote below)
Then you can just do:
Code:
tar -cvf ~/firefox-files.tar $(cat ~/firefox-files.txt)
And you will collect all the files (and their paths) into a single file, which can then be extracted with:
Code:
cd ~/firefox1
tar -xvf ~/firefox-files.tar
And you'll get the directory structure preserved.
(And for the benefit of anyone transferring between different machines, you can add -z to both tar commands to compress the tar file into a tgz (.tar.gz) which will transfer quicker.)
Nevermind, i copy the files and directories one by one. I guess there is no simple solution for what i am looking for.
Actually, there is:
Code:
tar c -T /path/to/filelist | tar x -C /path/to/targetdirectory
The first tar creates an archive and strips the leading '/' from the filenames. The second tar extracts the archive into the destination directory and preserves the directory structure.
Edit:
The main problem is that technically you do not have a filelist because it also contains directories and an "invalid" entry. So you will need to filter that list:
Code:
find $(</path/to/filelist) -maxdepth 0 -type f | tar c -T - | tar x -C /path/to/targetdirectory
or maybe (?)
Code:
find $(dpkg -L firefox) -maxdepth 0 -type f | tar c -T - | tar x -C /path/to/targetdirectory
Last edited by crts; 02-09-2020 at 01:00 PM.
Reason: filter for files only
Of course. That's because a pipe is needed to deal with the outout.
What happens when you put in the rest of the line as suggested?
Code:
tar c -T /path/to/filelist | tar x -C /path/to/targetdirectory
It works but the list have to contain only files. If it have directories it gives error like this:
Code:
tar: usr/bin: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
But with 'cpio' i don't have to clean the list first and remove directories, it works if it contain files and directories. So, i think 'cpio' is the better and simpler solution.
It works but the list have to contain only files. If it have directories it gives error like this:
Code:
tar: usr/bin: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
Well you'd already been offered two different solutions for how to filter dpkg output to be files only, but that error message is not because the list contains directories - it is pointing at the relative path "usr/bin", not the absolute path "/usr/bin". (Did you edit the file manually and make an editing mistake - have you verified no other mistakes were made?)
The same error message it output with cpio, however cpio skips invalid entries instead of aborting (tar can do the same with --ignore failed-read option).
If you corrected the path (or "cd /" first) then it will not error, (but it will include the entire contents of the /usr/bin directory, which is not what you want).
A second difference of cpio compared to tar is that when it see a directory in the list cpio only copies the directory, not its contents - a useful feature to know about, and one that I don't see an equivalent tar option for, which as you say does make cpio a more suitable option for this scenario.
One more note - the -u option overrides the default behaviour of skipping files that haven't changed or are newer, so I would consider not using it, especially if running the command multiple times.
tar: Refusing to write archive contents to terminal (missing -f option?)
tar: Error is not recoverable: exiting now
And the text file contain only list of files.
Honestly, I am completely lost here, OP. I just cannot fathom how you could possibly end up taking the course of action that you did. What you basically did is the equivalent of tying only one of your shoelaces and then complain that shoes do not work because you keep tripping.
I am genuinely curious, what was your thought process that made you cut off my proposed solution in the middle of the line and then come back here posting:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.