Search code examples
bashshellmintty

Shell: Copy list of files with full folder structure stripping N leading components from file names


Consider a list of files (e.g. files.txt) similar (but not limited) to

/root/
/root/lib/
/root/lib/dir1/
/root/lib/dir1/file1
/root/lib/dir1/file2
/root/lib/dir2/
...

How can I copy the specified files (not any other content from the folders which are also specified) to a location of my choice (e.g. ~/destination) with a) intact folder structure but b) N folder components (in the example just /root/) stripped from the path?

I already managed to use

cp --parents `cat files.txt` ~/destination

to copy the files with an intact folder structure, however this results in all files ending up in ~/destination/root/... when I'd like to have them in ~/destination/...


Solution

  • I think I found a really nice an concise solution by using GNU tar:

    tar cf - -T files.txt | tar xf - -C ~/destination --strip-components=1
    

    Note the --strip-components option that allows to remove an arbitrary number of path components from the beginning of the file name.

    One minor problem though: It seems tar always "compresses" the whole content of folders mentioned in files.txt (at least I couldn't find an option to ignore folders), but that is most easily solved using grep:

    cat files.txt | grep -v '/$' > files2.txt