vendredi 28 novembre 2014

Scripting multi-volume (GNU) `tar` with pre-defined number of volumes


I've wrote me a little script to test (or extract) a very big multi-volume tar archive (note: created with GNU tar), each of which 00x.tar chunk will fit onto a standard DVD:



#!/bin/bash
d=$(dirname $0)
prf="someprefix"
last=$(ls -1 $d/*.tar | wc -l)

for i in $(eval echo {2..$last}); do echo "n $prf.00$i.tar"; done | tar -Mtvf ./$prf.001.tar --wildcards "$1"


Notes:



  • The tar pipe will work with or without the $1 parameter given.

  • The d local will help in the case when both the volume and this script are at another place, but it is run from an arbitrary directory, e. g. your $HOME.

  • The last local will work around the issue of GNU tar to never check for number of available volumes in the working directory.

  • At this enormous size, $last will hardly ever get bigger than 5 (let alone 9) - hence the 00.


OK, this works. But getting rid of the loop altogether would be even better.

Like this (--wildcards ... left out here):



eval echo -e "n\ $d/$prf.00{2..$last}.tar\\\n" | tar -Mtvf ./$prf.001.tar


However, this only works with exactly two volumes. Set last to e. g. 4, and another issue will show up caused by echo when the pipe is omitted for a test:



n someprefix.002.tar
n someprefix.003.tar
n someprefix.004.tar


Ugh! How did that whitespace get in there? tar does not like that.


A "fix" (albeit very hackish) is to "sed out" the whitespace by inserting a | sed 's/^ //' into the above pipe. Quite ugly, but for heck, it works. :)


Can't the whitespace be avoided in the first place, as well?


(tr might not be a good solution here, because we'd need a substitute character (e. g. §) in order to preserve the first space after the n; save from dirty hacks, there is no way to tell tr "translate all _but_ the first space".)


UPDATE (Bye bye eval! Best solution so far, big thanks again to Mark P.)



seq -f "n $d/$prf.%03g.tar" 2 $last | tar -Mtvf $d/$prf.001.tar


Glad I asked. Way better than wasting resources on a for loop to accomplish such (fairly) simple task. Splendid!



Aucun commentaire:

Enregistrer un commentaire