Bash tar append file - bash

How to append file to tar, e.g. file located in /usr/file.txt?
I want to append it in tar to var/file.txt for future extract it into [tar location]/var/file.txt instead of [tar location]/usr/file.txt, using the
tar --append --file foo.tar bar
Is it possible to put file in tar this way without replacing /usr/file.txt to /var/file.txt before archiving?

If you're using GNU tar, there's a --transform option for that, which takes a sed-like expression as argument:
tar --append --file foo.tar --transform='s,^usr/,var/,' /usr/file.txt

The only way I can think of is to use a symlink var/file.txt -> /usr/file.txt.
mkdir var && ln -s /usr/file.txt var
tar --dereference --append --file foo.tar var

Related

Extract from tar file to different directory in Bash

I'm new to Bash and trying to unzip a tarball. Code so far:
#!/bin/bash
tar="/cdrom/java/jre1-8u181-x64tar.gz"
# Unpack tarball
gunzip < $tar | tar xf -
This extracts the archive in current directory. How can I specify a location?
Using Solaris 10, Bash 3.2.51
This works pretty well everywhere - including Solaris, and as you only change directory in a sub-shell, it doesn't affect your location in the current session:
gunzip < $tar | ( cd /some/where/else && tar xf -)
To extract the file to a specific directory
gunzip < $tar | tar -xf - --directory /path/to/extract/to
or
gunzip < $tar | tar -xf - -C /path/to/extract/to
As you wrote your command is unpacking in the current directory:
gunzip < $tar | tar xf -
Add the "-C" option to give it an alternate target directory:
gunzip < $tar | tar xf - -C /another/target/directory
Note that the Solaris tar does not understand the --directory option.
See the Solaris tar manpage.
Just for the sake of completeness if you have Gnu-Tar (which is available for Solaris too) you can use this simpler command (which unzips and unpacks in one go):
tar xzf $tar -C /another/target/directory
On a side note:
many people use a leading dash for the tar command parameters. That is redundant.
See the answers to this question if you are interested.
The -xf part of tar means to extract into the "f" file. try changing the tar command to something like
Edit
...| tar -xf - -C /path/to/your/desired/result/folder
sorry, #pitseeker is correct. The -C option tells tar to change directory then do the extract

How to remove empty directories from a tarball in-place

I extracted a layer from a docker image which archived in a file called layer.tar. I want to remove empty directories from it.
I don't want to unpack then repack files in that archive, I want to keep the original info, so I want to do it in-place.
I know how to delete files from tar but I don't know any simple method to delete empty directories in-place.
Let's create a archive t.tar with a/b/c/ and a/b/c/d/ empty directories:
mkdir -p dir
cd dir
mkdir -p a/b/c/d
mkdir -p 1/2/3/4
touch a/fil_ea a/b/file_ab # directory a/b/c and a/b/c/d are empty
touch 1/2/3/file_123 1/2/3/4/file_1234 # directories 1/2/3/4 not empty
tar cf ../t.tar a 1
cd ..
Using tar tf and some filtering we can extract the directories and files in a tar archive. Then for each directory in tmpdirs we can check if it has any files in tmpfiles with a simple grep and then remove those directories using --delete tar option:
tar tf t.tar | tee >(grep '/$' > tmpdirs) | grep -v '/$' > tmpfiles
cat tmpdirs | xargs -n1 -- sh -c 'grep -q "$1" tmpfiles || echo "$1"' -- \
| tac \
| xargs -- tar --delete -f t.tar
Not that tac is a bit unneeded, but the files where sorted alphabetically in tar, so when tar removes the directory a/b/c/ with all subdirectories first and then tries to remove a/b/c/d/ directory it fails with an Not found in archive in error. tac is a cheap way to fix that, so tar first removes a/b/c/d/ and then a/b/c/.

How to create an empty tgz file?

How to create an empty tgz file?
I tried
tar czvf /tmp/empty.tgz --from-file /dev/null
tar: Option --from-file is not supported
The switch you're looking for is --files-from or -T:
tar czvf /tmp/empty.tgz --files-from=/dev/null

How can I prevent tar from creating an empty archive?

/tmp/-> ls ab*
/tmp/-> ls: ab*: No such file or directory
/tmp/-> tar -cvf ab.tar abc*
tar: abc*: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors
/tmp/->
/tmp/-> ls ab*
ab.tar
/tmp/-> tar -tvf ab.tar
/tmp/->
As can be seen there are no files matching pattern abc*, however output file named ab.tar got created with no content. Is there a switch/option than can be passed to tar command so that no output file is created when there are no input file?
I’m fond of using a for-as-if construct for such cases:
for x in abc*; do
# exit the loop if no file matching abc* exists
test -e "$x" || break
# by now we know at least one exists (first loop iteration)
tar -cvf ab.tar abc*
# and since we now did the deed already… exit the “loop”
break
done
The body of the “loop” is run through exactly once, but the shell does the globbing for us. (I normally use continue in the place of the first break, but that’s probably not needed.)
Alternatively, you can use the shell to expand the glob into $*…
set -- abc*
test -e "$1" && tar -cvf ab.tar abc*
If your script runs under set -e, use if test …; then tar …; fi instead, otherwise it will abort when no file exists.
All these variants work in plain sh as well.
There is a way to get the shell to do it:
#!/bin/sh
# safetar -- execute tar safely
sh -O failglob -c 'tar cvf ab.tar abc*'
Is there a switch/option than can be passed to tar command so that no output file is created when there are no input file?
Gnu tar does not have such an option.
Here are two alternatives. You need to study them and figure out what would work for you, as they're a bit of a hack.
You could do something like:
Tar, test, remove when empty
tar -cvf ab.tar abc* ||
tar tf ab.tar | read ||
rm ab.tar
Explanation:
If tar -cvf ... fails, get the contents with tar tf ....
If the read fails, the archive was empty, and it's save to remove it.
Or you could try:
Test, then tar
ls abc* | read && tar -cvf ab.tar abc*
This would not create the empty tar file in the first place.

How to untar all tar files in current directory using Putty

How can I untar all tar files in one command using Putty.
I Tried the following but its not un-tarring (all files start with alcatelS*)
tar -xfv alcatelS*.tar
It is not working i don't get no errors and it is not un-tarring.
Thank you,
-xfv is wrong since v is being referred as the file instead. Also, tar can't accept multiple files to extract at once. Perhaps -M can be used but it's a little stubborn when I tried it. Also, it would be difficult to pass multiple arguments that were extracted from pathname expansion i.e. you have to do tar -xvM -f file1.tar -f file2.tar.
Do this instead:
for F in alcatelS*.tar; do
tar -xvf "$F"
done
Or one-line: (EDIT: Sorry that -is- a "one"-liner but I find that not technically a real one-liner, just a condensed one so I should haven't referred to that as a one-liner. Avoid the wrong convention.)
for F in alcatelS*.tar; do tar -xvf "$F"; done
You can use following command for extract all tar.gz files in directory in unix
find . -name 'alcatelS*.tar.gz' -exec tar -xvf {} \;
Following is my favorite way to untar multiple tar files:
ls *tar.gz | xargs -n1 tar xvf
Can be done in one line:
cat *.tar | tar -xvf - -i

Resources