tar exclude single files/directories, not patterns - tar

I'm using tar to make daily backups of a server and want to avoid backup of /proc and /sys system directories, but without excluding any directories named "proc" or "sys" somewhere else in the file tree.
For, example having the following directory tree ("bla" being normal files):
# find
.
./sys
./sys/bla
./foo
./foo/sys
./foo/sys/bla
I would like to exclude ./sys but not ./foo/sys.
I can't seem to find an --exclude pattern that does that...
# tar cvf /dev/null * --exclude=sys
foo/
or...
# tar cvf /dev/null * --exclude=/sys
foo/
foo/sys/
foo/sys/bla
sys/
sys/bla
Any ideas?
(Linux Debian 6)

You can specify absolute paths to the exclude pattern, this way other sys or proc directories will be archived:
tar --exclude=/sys --exclude=/proc /

Using tar you can exclude directories by placing a tag file in any directory that should be skipped.
Create tag files,
touch /sys/.exclude_from_backup
touch /proc/.exclude_from_backup
Then,
tar -czf backup.tar.gz --exclude-tag-all=.exclude_from_backup *

In this case you might want to use:
--anchored --exclude=sys/\*
because in case your tar does not show the leading "/" you have a problem with the filter.

Related

tar: unable to include folder but exclude content

I have a project folder with several directories
- archive
- include
- lib
- src
- src/obj (obj is a subdirectory of src)
I would like tar to pack these directories and their contents into a main.tar, then I will the main.tar into the archive directory.
tar cvz \
--exclude="*.obsolete" --exclude="*DS_Store" --exclude="./archive/*" \
-f main.tar \
./archive ./include ./lib ./src
I would like to exclude the contents of the archive directory but still package the empty directory itself. You can see I am also excluding some other stuff from various places, OSX likes to write .DS_Store files everywhere on my filesystem and I occasionally make copies of files and append .obsolete to the end while working on a new version.
Unfortunately, the empty archive directory is not included in main.tar.
According to this thread, my command should work.
How can the files be excluded from archive but the empty directory be packed into the tar file?
edit
The following fails:
--exclude="./archive/*"
The following works:
--exclude="./archive/*.*"
So the whole command is:
tar cvz \
--exclude="*.obsolete" --exclude="*DS_Store" --exclude="./archive/*.*" \
-f main.tar \
./archive ./include ./lib ./src

Tar does not exclude

I use
tar hczf t.tar.gz * --exclude="./test1"
where test1 is the name of a directory to exclude files from being tarred.
Unfortunately, tar still includes those directories. How can I have tar exclude directories?
The * that specifics "all files in the current directory" should be the last item on your cmd-line
tar --exclude="./test1" hczf t.tar.gz *
#--------------------------^-> tarFileName
#------------------------->f (for file)
This illustrates why the --excl... can't go inbetween hczf t.tar.gz.
The f option expects a filename right after it. So we have moved --excl... to the first option.
IHTH

Exclude common subdirectories when creating a tarball

I'm creating a tarball of a large codebase managed in ClearCase. Every directory has a sub-directory named ".CC". I'd like to exclude these from my tarball.
I've found Excluding directory when creating a .tar.gz file, but excluding that would appear to require passing each and every .CC directory on the commndline. This is impractical in my case.
Is there a way to exclude directories that meet a particular pattern?
EDIT:
I am not asking how to exclude a specific finite list of directories. I am asking how to exclude all directories that end in a particular pattern.
Instead of manually typing --exclude 'root/a/.CC' --exclude 'root/b/.CC' ... you can type $(find root -type d -name .CC -exec echo "--exclude \'{}\'" \;|xargs)
You can use whatever patterns find supports, or even use something like grep inbetween find and xargs.
The following bash script should do the trick. It uses the answer given by #Marcus Sundman.
#!/bin/bash
echo -n "Please enter the name of the tar file you wish to create with out extension "
read nam
echo -n "Please enter the path to the directories to tar "
read pathin
echo tar -czvf $nam.tar.gz
excludes=`find $pathin -iname "*.CC" -exec echo "--exclude \'{}\'" \;|xargs`
echo $pathin
echo tar -czvf $nam.tar.gz $excludes $pathin
This will print out the command you need and you can just copy and paste it back in. There is probably a more elegant way to provide it directly to the command line.
*.CC could be exchanged for any other common extension and this should still work.

tar --excludes option to exclude only the directory at current working directory, not subdirectories

I want to tar/zip a directory ./ (current working directory) and exclude files in the directory ./vendor, I happened to also have a subdirectory named vendor at ./public/web/vendor, but I want to keep that. I've tried:
tar cfz /private/var/folders/temp/mage6BRQWJ.tar.gz --exclude=vendor/* ./
tar cfz /private/var/folders/temp/mage6BRQWJ.tar.gz --exclude=./vendor/* ./
tar cfz /private/var/folders/temp/mage6BRQWJ.tar.gz --exclude="vendor/*" ./
But these both exclude the subdirectory.
I want to use relative path because I want to exclude all .svn (e.g. example) files from all directories, too.
Is there a way, using relative path , to exclude files in the ./vendor directory but not ./public/web/vendor ?
All you need is the --anchored tag:
GNU tar:
tar cfz mage6BRQWJ.tar.gz --anchored --exclude=vendor *
bsdtar:
bsdtar -czf mage6BRQWJ-1.tar.gz --exclude=^vendor *
That works.

Unpack tar.gz folder to part of filename

I have a file dagens_130325.tar.gz containing the folder dagens. In one folder I have hundreds of these daily info. I would like to unpack dagens_130325.tar.gz/dagens to 130325 with all the files inside. Then 130326 etc.
Is there a way to do it?
Not sure this is the right stack where to ask this kind of question, however try with
tar -zxvf dagens_130325.tar.gz -C /tmp/130325 dagens
This way, the folder dagens for the archive dagens_130325.tar.gz is going to be extracted into /tmp/130325. However, note that the target folder must exist, otherwise the command will fail
So, supposedly you have 4 archives in the form dagens_1.tar.gz, dagens_2.tar.gz, ..., you can write an extract.sh file containing
#!/bin/bash
for i in {1..4}
do
mkdir /tmp/$i
FILE="dagens_$i.tar.gz"
tar -zxvf $FILE -C /tmp/$i dagens
done
Having this file the execute permission, being in the same folder as your archives and executing it should produced the result you asked.
This was the solution I came up with in the end
#!/bin/bash
search_dir=/yourdir/with/tar.gz
for entry in "$search_dir"/*.tar.gz
do
substring=$(basename "$entry")
echo $substring
sub2=${substring:7:6}
tar -xvzf $substring
rm -rf $sub2
mv dagens $sub2
done
use
#!/bin/bash
for file in dagens_*.tar.gz
do
from=${file%_*} #removes chars after _
to=${file#*_} #removes chars before _
to=${to%.t*} #removes chars after .t (.tar.gz)
tar -zxf $file --show-transformed --transform "s/$from/$to/"
done

Resources