tar: intermediate directories

1 
1 B.2 Restoring Intermediate Directories
1 ======================================
1 
1 A common concern is how to extract permissions and ownerships of
1 intermediate directories when extracting only selected members from the
1 archive.  To illustrate this, consider the following archive:
1 
1      # tar tvf A.tar
1      drwxr-xr-x root/root         0 2017-11-16 14:39 foo/
1      dr-xr-x--- gray/user         0 2017-11-16 14:39 foo/bar/
1      -rw-r--r-- gray/user        10 2017-11-16 14:40 foo/bar/file
1 
1    Suppose you extract only the file 'foo/bar/file', while being 'root':
1 
1      # tar xvf A.tar foo/bar/file
1      foo/bar/file
1 
1    Now, let's inspect the content of the created directories:
1 
1      # find foo -ls
1      427257    0 drwxr-xr-x   3 root     root    16 Nov 17 16:10 foo
1      427258    0 drwxr-xr-x   2 root     root    17 Nov 17 16:10 foo/bar
1      427259    0 -rw-r--r--   1 gray     user    10 Nov  6 14:40 foo/bar/file
1 
1    The requested file is restored, including its ownership and
1 permissions.  The intermediate directories, however, are created with
1 the default permissions, current timestamp and owned by the current
1 user.  This is because by the time 'tar' has reached the requested file,
1 it had already skipped the entries for its parent directories, so it has
1 no iformation about their ownership and modes.
1 
1    To restore meta information about the intermediate directories,
1 you'll need to specify them explicitly in the command line and use the
1 '--no-recursive' option (⇒recurse) to avoid extracting their
1 content.
1 
1    To automate this process, 'Neal P. Murphy' proposed the following
1 shell script(1):
1 
1      #! /bin/sh
1      (while read path
1       do
1         path=`dirname $path`
1         while [ -n "$path" -a "$path" != "." ]
1         do
1           echo $path
1           path=`dirname $path`
1         done
1       done < $2 | sort | uniq) |
1       tar -x --no-recursion -v -f $1 -T - -T $2
1 
1    The script takes two arguments: the name of the archive file, and the
1 name of the file list file.
1 
1    To complete our example, the file list will contain single line:
1 
1      foo/bar/file
1 
1    Supposing its name is 'file.list' and the script is named
1 'restore.sh', you can invoke it as follows:
1 
1      # sh restore.sh A.tar file.list
1 
1    ---------- Footnotes ----------
1 
1    (1) The original version of the script can be seen at
1 <http://lists.gnu.org/archive/html/bug-tar/2016-11/msg00024.html>
1