We have a cpio archive that was created by generating a file that contains a list of absolute paths to be included in the archive. (one absolute path per line of a plain text file) The command to generate the archive is essentially:
cat list-of-files | cpio -ocvB > preserved.cpio
We later need to extract files from that archive. We again want to use a file that contains a list of files to be extracted (some subset of all of the files in the archive, again with the format of one absolute path per line of a plain text file).
cpio -icuBdmv `cat files-to-extract` < preserved.cpio
This works fine unless one of the paths contains a space. Generating the archive is fine, but when extracting the files, any file with a space in the name is silently skipped. All other paths in files-to-extract
are successfully extracted.
I've been playing at the console trying to come up with some way to work around this, but to no avail. If I specify a single file with a space in the name and wrap it in quotes, the file is extracted successfully:
# This extracts the file successfully
cpio -icuBdmv "/foo/bar/some file.txt" < preserved.cpio
So I could read files-to-extract
in a loop and extract each file one at a time, but these archives can be large (multiple GB), so that is dreadfully slow.
I tried a couple things to somehow try to either escape the spaces in file paths or quote each path value, but nothing I've tried has worked.
# Still skips the file with spaces:
cpio -icuBdmv `cat files-to-extract | sed 's/ /\\ /'` < preserved.cpio
# Extracts no files, even the ones without spaces:
cpio -icuBdmv `cat files-to-extract | sed 's/\(.*\)/"\1"/'` < preserved.cpio
It would really be nice to be able to do this extraction with a single run of cpio rather than having to loop and extract one file at a time. I'm sure this is just a problem with how I am providing those values to cpio, but for the life of me I cannot figure out why.
Probably not relevant, but just for completeness: this is on CentOS 7.2, using GNU cpio 2.11
$( )
substitution doesn't work, unless eval'ed or otherwise reparsed which gets very tricky. What you can do is setIFS='\n'
before the command, preferably in a subshell so it automatically reverts:( IFS='\n'; cpio -icuBdmv $(cat names) <archive )
. But note if the substituted results are too big for your system's ARG_MAX this will fail, whilexargs
as in @Ian's answer will break it into groups small enough to run but still much larger and more efficient than one at a time.info
, but still, I should have seen the-E
option where I was looking. Works like a charm, thanks!pinfo
rather than the FSF's owninfo
. Thepinfo
UI is kind of likelynx
, but for info files. I'd still prefer to have a proper man page (with at least a summary description of each option) as well as the .info reference manual.