Tar does not exclude - tar

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

Related

Dockerignore: allow to add only specific extension like *.json from any subfolder

I have a .dockerignore file and I'm trying to allow Docker to upload only *.json files but from any of subfolders.
For example, for the next files structure:
public/readme.md
public/subfolder/a.json
public/subfolder/b.json
public/other/c.json
public/other/file.txt
I'm expecting to see only json files in the image:
public/subfolder/a.json
public/subfolder/b.json
public/other/c.json
Of course they must be located in the same directories as in original source.
I tried several ways but didn't succeed.
UP: I don't know how many subfolders will be created in the public/ directory and how deep will be the directories structure.
I think you can achieve what you want by relying on one such .dockerignore:
public/*
!public/subfolder
public/subfolder/*
!public/other
public/other/*
!**/*.json
The tricky thing is that the first line of this file is public/* but not public nor * (otherwise the !... subsequent lines won't work).
Note also that you may want to automate the generation of one such .dockerignore, to cope with possible tree structure changes.
For example:
gen-dockerignore.sh
#!/usr/bin/env bash
{ echo '*' ; # header of the .dockerignore - to be changed if need be
find public -type d -exec echo -en "!{}\n{}/*\n" \; ;
echo '!**/*.json' ; } > .dockerignore
$ ./gen-dockerignore.sh would output the following file:
.dockerignore
*
!public
public/*
!public/other
public/other/*
!public/subfolder
public/subfolder/*
!**/*.json

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

How could I untar all .tar files in a directory to folders based on filename of each .tar?

I could do this for .zip files in the folder using the command below:
for f in "!"; do unzip -d "${f%*.zip}" "$f"; done
The above command extracts all .zip files in a given folder to subfolders, having content and name of respective .zip files.
But I couldn't find a command that would do the same for .tar files. Please help.
Btw, I am trying to do this on a remote server using WinSCP/putty. So, I cannot use a GUI software. I need a command, thus the question.
After a bit of fiddling I came up with for f in $(find -maxdepth 1 | grep .tar); do mkdir ${f%.tar}; tar -xaf $f -C ${f%.tar} ; done appears to work, so long as the file name does not contain any spaces. I assume you wanted the directory from foo.tar to be named foo (no file extension). If you want the directory to be named foo.tar (with file extension) then try using for f in $(find -maxdepth 1 | grep .tar); do mkdir $f ; tar -xaf $f -C $f ; done.
IIRC, the remote access client Cyberduck can handle compressed files in a GUI - so you can try that if you're fine with a GUI solution.

extract a file from xz file

I have a huge file file.tar.xz containing many smaller text files with a similar structure. I want to quickly examine a file out of the compressed file and have a glimpse of files content structure. I don't have information about names of the files within the compressed file. Is there anyway to extract a single file out given the above the above scenario?
Thank you.
EDIT: I don't want to tar -xvf file.tar.xz.
Based on the discussion in the comments, I tried the following which worked for me. It might not be the most optimal solution, the regex might need some improvement, but you'll get the idea.
I first created a demo archive:
cd /tmp
mkdir demo
for i in {1..100}; do echo $i > "demo/$i.txt"; done
cd demo && tar cfJ ../demo.tar.xz * && cd ..
demo.tar.xz now contains 100 txt files.
The following lists the contents of the archive, selects the first file and stores the path within the archive into the variable firstfile:
firstfile=`tar -tvf demo.tar.xz | grep -Po -m1 "(?<=:[0-9]{2} ).*$"`
echo $firstfile will output 1.txt.
You can now extract this single file from the archive:
tar xf demo.tar.xz $firstfile

tar exclude single files/directories, not patterns

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.

Resources