How to tar a branch of file tree? - linux

I currently have some files and directories at this path:
/var/tmp/mydir/
I want to tar the whole path, excluding any other content in 'var' and 'tmp'.
Example:
$ ls /var
tmp
dir1 *(exclude)*
file1 *(exclude)*
$ ls /var/tmp
mydir
dir2 *(exclude)*
file2 *(exclude)*
$ ls /var/tmp/mydir
tarme1
tarme2
tarme3
In this case, I want to tar the directory tree /var/tmp/mydir and the content of 'mydir'.

Use tar -cf <archive_name>.tar /var/tmp/mydir which will give you what you need.
Use man tar to get more help (should be quite easy to understand).
If you want to modify your path some other way consider using -C switch. From man:
-C, --directory DIR
change to directory DIR

Do
tar -c --recursion --file backup.tar tmp/mydir
and
tar -tvf backup.tar
gives me :
drwxrwxr-x ssam/ssam 0 2016-05-02 12:02 tmp/mydir/
-rw-rw-r-- ssam/ssam 0 2016-05-02 12:02 tmp/mydir/tarme3
-rw-rw-r-- ssam/ssam 0 2016-05-02 12:02 tmp/mydir/tarme1
-rw-rw-r-- ssam/ssam 0 2016-05-02 12:02 tmp/mydir/tarme2
which is what you need. You can extract/restore it using
tar -xf backup.tar -C /var
Remember this will overwrite the files in mydir

Related

Why find piped to xargs mv deleted my files?

Today I experienced something unbelievable. My goal was to mv files newer than 7 days to another directory. The directory exist.
I used command:
find ./* -newermt $(date +%Y-%m-%d -d '7 day ago') -type f -print | xargs -I '{}' mv {} ../update_error_handled
Then, unbelievably the files were gone, I went to the folder used ls -lA and didn't found any files I moved. What happened? CentOS 7.0, there were no directory mount, original files missing, tried to grep -r "content" / - found nothing... .
So why it did behave that way?
Beforehand I launched
find ./* -newermt $(date +%Y-%m-%d -d '7 day ago') -type f -print it returned:
./file66.xml
./file67.xml
...etc.
It really do sucks to lose data in such a way.
To clarify: Directory existed before moving files. Directory does not contain my files I tried to move today, only older ones.
Did you create in advance a directory at ../update_error_handled?
If not, then all that you have left from the files will be the last one, which will be called ../update_error_handled.
In order to avoid such mistakes, I always make sure that the destination directory exists, by adding /. at the end of the destination directory name.
Unsafe approach:
$ rm -rf file dest_dir
$ touch file
$ ls -ld file dest_dir
ls: cannot access 'dest_dir': No such file or directory
-rw-rw-r--. 1 u u 0 Sep 28 11:53 file
$ mv file dest_dir
$ ls -ld file dest_dir
ls: cannot access 'file': No such file or directory
-rw-rw-r--. 1 u u 0 Sep 28 11:53 dest_dir
Using the unsafe approach, file was renamed to a file named dest_dir.
Safe approach:
$ rm -rf file dest_dir
$ touch file
$ ls -ld file dest_dir
ls: cannot access 'dest_dir': No such file or directory
-rw-rw-r--. 1 u u 0 Sep 28 11:54 file
$ mv file dest_dir/.
mv: cannot move 'file' to 'dest_dir/.': No such file or directory
$ ls -ld file dest_dir
ls: cannot access 'dest_dir': No such file or directory
-rw-rw-r--. 1 u u 0 Sep 28 11:54 file
Using the safe approach, the mv command failed and the file file remained intact.

Getting stat (ls or cp) of hidden files

I have a folder with a .tmux.conf file under source control, and I would like to copy that file over to ~. Here is an ls of that:
ubuntu#ip-172-180:~$ ls -alh .vim/others
total 12K
drwxrwxr-x 2 ubuntu ubuntu 4.0K May 2 19:05 .
drwxrwxr-x 6 ubuntu ubuntu 4.0K May 2 19:05 ..
-rw-rw-r-- 1 ubuntu ubuntu 706 May 2 19:05 .tmux.conf
However, when I do ls on that directory, I get nothing:
ubuntu#ip-172-30-1-180:~$ ls .vim/others/*
ls: cannot access '.vim/others/*': No such file or directory
Same with cp:
ubuntu#ip-172-30-1-180:~$ cp .vim/others/* .
cp: cannot stat '.vim/others/*': No such file or directory
Is there some additional parameter I have to add when copying over dot files?
check this command
ls -ld .[!.]*
ls -ld .vim/others/[!.]*

Print the first line of each file inside a tar.gz without extracting

I'm looking for a command in order to print the first line of every file contained in a tar.gz archive, without extracting it.
Example:
tar -ztvf MyArchive.tar.gz
-rw-r--r-- root/root 3732541752 2020-04-04 03:24 FILE1.TXT
-rw-r--r-- root/root 90493394 2020-04-04 03:16 FILE2.TXT
-rw-r--r-- root/root 103294570 2020-04-03 21:06 FILE3.TXT
-rw-r--r-- root/root 16865694 2020-04-03 21:07 FILE4.TXT
-rw-r--r-- root/root 13176227988 2020-04-03 23:36 FILE5.TXT
I need to print the first line of each FILE*.TXT inside the tar.gz
How can I achieve this?
You could achieve using tar and for loop commands.
for i in $(tar -ztvf MyArchive.tar.gz|grep -i file|awk '{print $NF}')
do
tar xfO MyArchive.tar.gz $i|head -1
done
Using "tar xfO MyArchive.tar.gz filename" to read the content of files inside tar.gz
Try this:
tar zxf MyArchive.tar.gz --to-command="head -n 1"
This command takes files in the tar individually and feeds them into the command "head -n 1".

tar creates an empty folder, how do i get rid of it?

I have the following line
tar -c -v -z -f "$ARCHIVE_PATH/$3_$fileYear$fileMonth.tar.gz" -C "$ARCHIVE_PATH/tmp" .
where
$ARCHIVE_PATH = /opt/colorado/archive/
$3 = IMPORT
$fileYear = 2014
$fileMonth = 06
so the line creates a .tar.gz file called IMPORT_201406.tar.gz in /opt/colorado/archive/ from the files located in /opt/colorado/archive/tmp/
however when i use tar -ztvf "opt/colorado/archive/IMPORT_201406.tar.gz" i see this
-rwxr-xr-x root/root 27 2014-06-04 14:20 ./afile.txt
drwxr-xr-x root/root 0 2014-06-04 14:08 ./opt/
drwxr-xr-x root/root 0 2014-06-04 14:08 ./opt/colorado/
drwxr-xr-x root/root 0 2014-06-04 14:08 ./opt/colorado/archive/
drwxrwxr-x [USER]/[USER] 0 2014-06-04 14:09 ./opt/colorado/archive/tmp/
-rwxr-xr-x root/root 712 2014-06-04 14:20 ./twofile.txt
-rwxr-xr-x root/root 383 2014-06-04 14:20 ./random.cvs
-rwxr-xr-x root/root 27 2014-06-04 14:20 ./helloworld.sh
-rwxr-xr-x root/root 7938 2014-06-04 14:20 ./helloworld.py
from my understanding, if i didn't have -C the /opt/colorado/archive/tmp/ would have been added to every file so adding -C tells tar to move to that directory first, i can see in the list of files however why is the /opt/colorado/archive/tmp/ folder added and is there a way to remove it?
It's adding the directory to the archive because you asked it to. Specifically, you told tar to archive the directory ., so that's what it does. Computers tend to be literal.
If you don't want the directory archived, you'll have to pass the filenames in the directory to tar. Here's one way to do that:
(cd "$ARCHIVE_PATH/tmp"; ls) |
tar -cvzf "$ARCHIVE_PATH/$3_$fileYear$fileMonth.tar.gz" -C "$ARCHIVE_PATH/tmp" -T-
Alternatively, you can execute tar from the directory with the files:
cd "$ARCHIVE_PATH/tmp"; tar -cvzf "$ARCHIVE_PATH/$3_$fileYear$fileMonth.tar.gz" *
I don't know why you get the directory included with its full path, rather than just ., and why it also includes the parent directories in the archive. The version of tar on my system (tar (GNU tar) 1.26) doesn't seem to do that.
This command will generate the tar file:
tar -cvf new.tar.gz my_dir_to_tar/
where new.tar.gz = tar file name
and my_dir_to_tar/ = directory to make a tar

Compressing a list of files contain spaces in their file-names

I’ve been trying to compress a set of files contain spaces in thier file-names using a bash file. The bash file is:
#!/bin/bash
tar -cPf 'myconfigs.tar' `cat myconfigs.list`
The content of myconfigs.list file is:
/home/anas/.config/chromium/Default/Bookmarks
/home/anas/.config/chromium/Default/Login Data
/home/anas/.config/chromium/Default/Login Data-journal
The problem is that files contain spaces in their file-names don’t be included in the result TAR archive.
I tried '', "", %20... but didn’t work.
Thanks for your help in advance.
Anas,
I think you need to use:
tar -cPf myconfigs.tar -T myconfigs.list
instead of your "cat" . cat should work too if you properly escape the filenames inside, but -T is better.
UPDATED (to address your question in question's comments):
I cannot comment in your question (don't have enough reputation), so I decided to improve my answer instead.
The tilde (~) expansion is a shell thing, tar does not support it. However, to achieve what you want to achieve, you can use the following trick:
use relative paths in your myconfigs.list file (relative to the home directory):
.config/chromium/Default/Bookmarks
.config/chromium/Default/Login Data
.config/chromium/Default/Login Data-journal
run tar in such way that it changes directory to your home on startup:
tar -cPf myconfigs.tar -C ~/ -T myconfigs.list
OK, I went ahead and created a sample session illustrating it:
root#web:~ # useradd -m galaxy
root#web:~ # su - galaxy
galaxy#web:~ $ mkdir -p {1,2}/{3,4}/{5,6,7}
galaxy#web:~ $ find . -xdev -type d -exec touch '{}/file.txt' \;
galaxy#web:~ $ cat << EOF > include.lst
> 1/3
> 1/4/5/file.txt
> 1/4/7
> 2/file.txt
> EOF
galaxy#web:~ $ cd 2/3/6
galaxy#web:~/2/3/6 $ tar cjSpf ~/sample.tar.bz2 -C ~/ -T ~/include.lst
galaxy#web:~/2/3/6 $ cd
galaxy#web:~ $ tar tjvf sample.tar.bz2
drwx------ galaxy/galaxy 0 2014-02-19 04:10 1/3/
-rw------- galaxy/galaxy 0 2014-02-19 04:10 1/3/file.txt
drwx------ galaxy/galaxy 0 2014-02-19 04:10 1/3/7/
-rw------- galaxy/galaxy 0 2014-02-19 04:10 1/3/7/file.txt
drwx------ galaxy/galaxy 0 2014-02-19 04:10 1/3/6/
-rw------- galaxy/galaxy 0 2014-02-19 04:10 1/3/6/file.txt
drwx------ galaxy/galaxy 0 2014-02-19 04:10 1/3/5/
-rw------- galaxy/galaxy 0 2014-02-19 04:10 1/3/5/file.txt
-rw------- galaxy/galaxy 0 2014-02-19 04:10 1/4/5/file.txt
drwx------ galaxy/galaxy 0 2014-02-19 04:10 1/4/7/
-rw------- galaxy/galaxy 0 2014-02-19 04:10 1/4/7/file.txt
-rw------- galaxy/galaxy 0 2014-02-19 04:10 2/file.txt
galaxy#web:~ $
This should give you a start :)
Don't use cat's output like that otherwise space is considered a delimiter and a separete argument to the tar command.
You can use -T tar option:
tar -cPv -T myconfigs.list -f myconfigs.tar

Resources