Extracting few files without scanning whole tar.gz - bash

I would like to extract few files from one directory in tar.gz. The problem is that in the location I find a lot of files and the process of unpacking the whole folder is inefficient. I tried to extract them individually, but before extracting a particular file it scans the entire package. Is there a way to skip a scan and extract directly?
script for extracting a single file one by one:
filesList=( "file1" "file2" "file3" )
filesPath="path/to/files/inside/targz/"
for i in "${filesList[#]}"
do
tar -xvf compressed.tar.gz $filesPath$i
done

To extract a specific file from tar you can use:
tar -zxvf <tar_name> <file_to_untar>

Not sure to unserdstand what is the scan (maybe in another part of the script). The for loop can be avoided and tar called once.
tar -xvf compressed.tar.gz "${filesList[#]/#/$filesPath}"
or process the list first
filesList=( "file1" "file2" "file3" )
filesPath="path/to/files/inside/targz/"
filesPathList=()
for i in "${filesList[#]}"
do
filesPathList+=("$filesPath$i")
done
tar -xvf compressed.tar.gz "${filesPathList[#]}"
I've just seen it's a tar.gz, so inflated (gzip -cd or zcat) inside the loop. Which explain the poor performance, another option can be to gunzip first.

Related

How to tail the last nth lines of a file that is located in a compressed tar file

Ubuntu 16.04
Bash 4.4.20
I am wanting to tail the last 30 lines of a SQL file located in a tar.gz file. I noticed that the SQL backups were failing due to a locked file. Instead of me untarring the entire compressed file, I'd like to simply tail the SQL backup and then grep for certain phrases.
This StackOverflown Thread explains that this is not possible with zipped files. Does this also apply to tar files that are created like so:
tar czf name.tar.gz foldername
If this has been explained in another thread, please delete this thread and I'll keep searching.
You can use tar's -O option to print content of file then using | (pipe), you can apply basic unix operations, like tail:
tar zxvf name.tar.gz <file_to_read> -O | tail
Sample command, to read last two lines of a file A1.txt
tar zxvf B.tar.gz B/A1.txt -O | tail -2
Here B is a directory on which I have ran tar command, it contains many files along with file A1.txt

View several lines from a file in a tar.gz file

I have a very large .tar file that contains several .gz files. I would like to view a few lines in any of the individual files without untarring. I can view the files using:
tar -tzf TarFile # doesn't actually end in .tar
I get:
TarFile/
FileA.gz
FileB.gz
FileC.gz
FileD.gz
I would like to view just a few lines from any of the individual files. Normally I would use:
zless MyFile
Is there a way to combine the two commands so I can view a few lines from any of the individual files?
tar -xOf TarFile FileB.gz | zless
Explanation:
tar
-x
-O extract to standard output
-f Tarfile
FileB.gz the file in the tar archive to extract
| zless pipe the extracted file data to zless
This will be expensive to do more than once as it requires tar to scan the archive each time you run the command. If the tar archive is large (and the file you want is early in the tarball) you might also benefit from using --occurrence=1 on that command line to get tar to stop processing the tar file immediately when it finds a file that matches the file you told it to extract.

Searching a file inside a .tar.gz file by date in unix

I would like to ask if there is a way to search for a file inside a .tar.gz file without extracting it? If there is, is there a way to search for that file by date?
My OS is AIX.
Thanks!
tar can be instructed to preserve atimes on files it archives, but not all tars do this, and I am unfortunately not familiar with AIX-specific tar in this case. What you need to know is whether tar was invoked with --atime-preserve (AIX tar may not support this; be sure to check), and when you call an extraction you must use the -p flag. So, you'd have something like this:
tar zxpf file.tar.gz the/file/you/want.txt
You will likely find that Unix (cf Linux) tar won't support the -j and -z so you would have to use:
gzip -dc file.tar.gz | tar xf - the/file/you/want.txt
to run the command from a pipe. In this case, you would need to know the name of the file you want extracted, which you can get from:
tar tf file.tar.gz
using compression as required. Obviously you can tack on a | grep foo if you are looking for a file named foo.
It is not, I do not think, possible to extract a file from tar based upon the modification date of the file in the tarball – at least I was not able to find support for such in the documentation. Remember, tar is just the tape archiver and is not meant to do such fancy things. :-)
Lastly, you can do this:
tar xvf file.tar `tar tf file.tar | grep foo`
if you want to pull out all the files matching 'foo' from file.tar (compression above yada yada). I do not suggest running that command on an actual tape drive!
$ tar tzf archive.tar.gz | grep "search"

Bash shell script to glob files in several directories, add to an archive and remove original file

I am trying to write a bash script that does the following:
Enumerates through list of files in a directory, that match a specified pattern
Creates a tar file containing the matching files
Removes (i.e. deletes) the matched files from their source directories
To keep things simple, I intend to use a hard coded list of directories and file patterns
This is what I have come up with so far:
#!/bin/bash
filenames[0]='/home/user1/*.foo'
filenames[1]='/some/otherpath/*.fbar'
for f in ${filenames[#]}
do
echo "$f"
done
However, I am unusure on how to proceed from this point onward. Specifically, I need help on:
How to glob the files matching the pattern $f
How to add the ENTIRE list of matching files (i.e. from all directories) to a tar file in one go
Regarding deleting the files, I am thinking of simply iterating through the ENTIRE list obtained in step 2 above, and 'rm' the actual file - is there a better/quicker/more elegant way?
PS:
I am running this on Ubuntu 10.0.4 LTS
If you want to use a loop because you have many directories, you can use the -r option to append to the tar file. You can also use --remove-files to remove files after adding them to the archive.
filenames[0]='/home/user1/*.foo'
filenames[1]='/some/otherpath/*.fbar'
for f in "${filenames[#]}"
do
tar -rvf --remove-files foo.tar $f
done
If you don't have the --remove-files option, use rm $f after the tar command.
tar(1) supports an --remove-files option that will remove the files after adding them to the archive.
Depending upon what you're trying to do with your shell globs, you might be able to ignore doing all that extra work there, too. Try this:
tar cf /dir/archive.tar --remove-files /home/user1/*.foo /some/otherpath/*.fbar

Automated unzipping of files

I have a folder full of zipped files (about 200). I would like to transform this into a folder consisting only of unzipped files. What would be the easiest and quickest way to do this?
Please note that I would like to remove the zipped file from the folder once it us unzipped.
Also, I'm on a Mac.
Thanks!
You can do something like:
for file in `ls *.zip`; do unzip -f $file; rm $file; done
We are looping through all the zip files in the directory, unzipping it and then deleting it.
Note that the -f option of zip will overwrite any file without prompting if it finds a duplicate.
You need to run the above one-line command on the command line from the directory that has the all the zip files. That one line is equivalent to:
for file in `ls *.zip` # ls *.zip gets the list of all zip file..iterate through that list one by one.
do # for each file in the list do the following:
unzip -f $file # unzip the file.
rm $file # delete it.
done
I found this answer which is a simple one liner to gunzip all .gz compressed files within a folder.
Basically you cd to the folder and then run
gunzip *.gz
If you want to only unzip files with a certain prefix you put that before the *
gunzip example*.gz
Easy as cake!

Resources