Man page - gztool(1)
Packages contains this manual
Manual
gztool
NAMESYNOPSIS
DESCRIPTION
OPTIONS
QUICK EXAMPLE
MORE EXAMPLES
INTERNALS
PROJECT HOME PAGE
SEE ALSO
AUTHOR
NAME
gztool - extract random-positioned data from gzip files, even like ātail -fā
SYNOPSIS
gztool [Ā [-[abLnsv]Ā #]Ā [-[1..9]AcCdDeEfFhilpPqrRStTwWxXzZ|u[cCdD]]Ā [-IĀ <INDEX>]Ā ]Ā "files"Ā ...
Note that actions ā-bcStTā proceed to an index file creation (if none exists) INTERLEAVED with data flow. As data flow and index creation occur at the same time thereās no waste of time. Also you can interrupt actions at any moment and the remaining index file will be reused (and completed if necessary) on the next gztool run over the same data.
DESCRIPTION
gztool is a GZIP files indexer, compressor and data retriever. It can create small indexes for gzipped files and use them for quick and random-positioned data extraction.
gztool can extract random-positioned data from gzip files with no penalty, including gzip tailing like with ātail -fā.
gztool creates an index file (.gzi) for every gzip it treats, and this action is interleaved with compression/uncompression so thereās no waste of time. Any action can be interrupted at any moment, and the remaining index will be reused on next runs.
Extraction is possible from any byte (or line) position in the uncompressed data using ā-bā (or ā-Lā for lines).
If the uncompressed file is a text file, then using the ā-xā modifier the index will take care of lines, so later gztool can be requested to extract data from a particular line with ā-Lā.
See the full listing of capabilities on INTERNALS.
OPTIONS
|
files |
One or more files. If no file is indicated, standard input is used. |
-[1..9]
compression factor to use with ā-[c|u[cC]]ā, from best speed (ā-1ā) to best compression (ā-9ā). Default is ā-6ā.
|
-aĀ # |
Await # seconds between reads when ā-[ST]|Ecā. Default is 4 s. |
||
|
-A |
modifier for ā-[rR]ā to indicate the range of bytes/lines in absolute values, instead of the default incremental values. |
||
|
-bĀ # |
extract data from indicated uncompressed byte position of gzip file (creating or reusing an index file) to STDOUT. Accepts ā0ā, ā0xā, and suffixes ākmgtpeā (Ė10) or āKMGTPEā (Ė2). |
||
|
-C |
always create a āCompleteā index file, ignoring possible errors. |
||
|
-c |
compress a file like with gzip, creating an index at the same time. |
||
|
-d |
decompress a file like with gzip. |
||
|
-D |
do not delete original file when using ā-[cd]ā. |
||
|
-e |
if multiple files are indicated, continue on error (if any). |
||
|
-E |
end processing on first GZIP end of file marker at EOF. Nonetheless with ā-cā, ā-Eā waits for more data even at EOF. |
||
|
-f |
force file overwriting if destination file already exists. |
||
|
-F |
force index creation/completion first, and then action: if ā-Fā is not used, index is created interleaved with actions. |
||
|
-h |
print brief help; ā-hhā prints this help. |
||
|
-i |
create index for indicated gzip file (For āfile.gzā the default index file name will be āfile.gziā). This is the default action. |
-IĀ string
index file name will be the indicated string.
|
-l |
check and list info contained in indicated index file. ā-llā and ā-lllā increase the level of index checking detail. |
||
|
-LĀ # |
extract data from indicated uncompressed line position of gzip file (creating or reusing an index file) to STDOUT. Accepts ā0ā, ā0xā, and suffixes ākmgtpeā (Ė10) or āKMGTPEā (Ė2). |
||
|
-nĀ # |
indicates that the first byte on compressed input is #, not 1, and so truncated compressed inputs can be used if an index exists. |
||
|
-p |
indicates that the gzip input stream may be composed of various incorrectly terminated GZIP streams, and so then a careful Patching of the input may be needed to extract correct data. |
||
|
-P |
like ā-pā, but when used with ā-[ST]ā implies that checking for errors in stream is made as quick as possible as the gzip file grows. Warning: this may lead to some errors not being patched. |
||
|
-q |
extract data as indicated with ā-[bL]ā of a still-growing gzip file and continue Supervising & extracting to STDOUT even after eof. |
||
|
-rĀ # |
(range): Number of bytes to extract when using ā-[bL]ā. Accepts ā0ā, ā0xā, and suffixes ākmgtpeā (Ė10) āKMGTPEā (Ė2). |
||
|
-RĀ # |
(Range): Number of lines to extract when using ā-[bL]ā. Accepts ā0ā, ā0xā, and suffixes ākmgtpeā (Ė10) āKMGTPEā (Ė2). |
||
|
-sĀ # |
span in uncompressed MiB between index points when creating the index. By default is ā10ā. |
||
|
-S |
Supervise indicated file. Create a growing index, for a still-growing gzip file. (ā-iā is implicit). |
||
|
-t |
tail (extract last bytes) to STDOUT on indicated gzip file. |
||
|
-T |
tail (extract last bytes) to STDOUT on indicated still-growing gzip file, and continue Supervising & extracting to STDOUT. |
-uĀ [cCdD]
utility to compress (ā-u cā) or decompress (ā-u dā) zlib-format files to STDOUT. Use ā-u Cā and ā-u Dā to manage raw compressed files. No index involved.
|
-vĀ # |
output verbosity from ā0ā (none) to ā5ā (nuts). Default is ā1ā (normal). |
||
|
-w |
wait for creation if file doesnāt exist, when using ā-[cdST]ā. |
||
|
-W |
do not Write index to disk. But if one is already available read and use it. Useful if the index is still under a ā-Sā run. |
||
|
-x |
create index with line number information (win/*nix compatible). |
Please, note that
gztoolās index counts last line even if the last char
isnāt a newline char - whilst āwcā command
will not count it in this case!.
This is implicit unless ā-Xā or ā-zā
are indicated.
|
-X |
like ā-xā, but newline character is ā\rā (old mac). |
||
|
-z |
create index without line number information. |
||
|
-Z |
adjust index points to a byte boundary: no previous byte needed. |
QUICK EXAMPLE
Extract data from 1 GiB byte (byte 2Ė30) on, from āmyfile.gzā to the file āmyfile.txtā. Also gztool will create (or reuse, or complete) an index file named āmyfile.gziā:
$Ā gztoolĀ -bĀ 1GĀ myfile.gzĀ >Ā myfile.txt
MORE EXAMPLES
* Make an index for ātest.gzā. The index will be named ātest.gziā:
$Ā gztoolĀ -iĀ test.gz
* Make an index for ātest.gzā with name ātest.indexā, using ā-Iā:
$Ā gztoolĀ -IĀ test.indexĀ test.gz
* Also ā-Iā can be used to indicate the complete path to an index in another directory. This way the directory where the gzip file resides could be read-only and the index be created in another read-write path:
$Ā gztoolĀ -IĀ /tmp/test.gziĀ test.gz
* Retrieve data from uncompressed byte position 1000000 inside test.gz. Index file will be created at the same time (named ātest.gziā):
$Ā gztoolĀ -bĀ 1mĀ test.gz
* Supervise an still-growing gzip file and generate the index for it on-the-fly . The index file name will be āopenldap.log.gziā in this case. āgztoolā will execute until interrupted (it can also stop at first end-of-gzip data with ā-Eā):
$Ā gztoolĀ -SĀ openldap.log.gz
* The previous command can be sent to background and with no verbosity, so we can forget about it:
$Ā gztoolĀ -v0Ā -SĀ openldap.log.gzĀ &
Creating and index for all "*gz" files in a directory:
$Ā gztoolĀ -iĀ *gz
* Extract data from āproject.gzā byte at 1 GiB to STDOUT, and use āgrepā on this output. Index file name will be āproject.gziā:
$Ā gztoolĀ -bĀ 1GĀ project.gzĀ |Ā grepĀ -iĀ "balanceĀ =Ā "
* Please, note that STDOUT is used for data extraction with ā-bcdtTā modifiers, so an explicit command line redirection is needed if output is to be stored in a file:
$Ā gztoolĀ -bĀ 99mĀ project.gzĀ >Ā uncompressed.data
* Extract data from a gzipped file which index is still growing with a āgztool -Sā process that is monitoring the (still-growing) gzip file: in this case the use of ā-Wā will not try to update the index on disk so the other process is not disturb! (Note that āgztoolā always tries to update the index used if it thinks itās necessary):
$Ā gztoolĀ -WbĀ 100kĀ still-growing-gzip-file.gzĀ >Ā mytext
* Extract data from line 10 million, to STDOUT:
$Ā gztoolĀ -LĀ 10mĀ compressed_text_file.gz
* Nonetheless note that if in the precedent example an index was previously created for the gzip file without the ā-xā parameter (or not using ā-Lā), as it doesnāt contain line numbering info , āgztoolā will complain and stop. This can be circumvented by telling āgztoolā to use another new index file name (ā-Iā), or even not using anyone at all with ā-Wā (do not write index) and an index file name that doesnāt exists (in this case āNoneā - it wonāt be created because of ā-Wā), and so ((just) this time) the gzip will be processed from the beginning:
$Ā gztoolĀ -LĀ 10mĀ -WIĀ NoneĀ compressed_text_file.gz
* Extract data from line 10 million, to STDOUT, on a still-growing file (ā-qā), so if that line number still has not been reached, āgztoolā will patiently wait until the gzip file grows enough to store that line, and show just it (ā-R 1ā). ā-qā to wait for content can be used with both ā-Lā (line numbers) and ā-bā (byte positions):
$Ā gztoolĀ -qĀ -LĀ 10mĀ -RĀ 1Ā compressed_text_file.gz
* Extract all data from a rsyslogās veryRobustZip (//www.rsyslog.com/doc/v8-stable/configuration/modules/omfile.html#veryrobustzip) that contains dirty data. This *corrupted-gzip-files* can arise when using rsyslogās veryRobustZip omfile option and the process that is logging is abruptly terminated and then restarted - this produces an incorrectly-terminated-gzip stream that is followed by another gzip stream in the same file . āgzipā (nor āzlibā) cannot read this files beyond the point of error. But āgztoolā can correctly extract all data (and only good data) using ā-pā (*patch*) parameter:
$Ā gztoolĀ -pĀ -b0Ā compressed_text_file.gz
This creates, as usual, the index file ācompressed_text_file.gziā. In order to not create it, ā-Wā ( do not Write index ) can be used:
$Ā gztoolĀ -pWb0Ā compressed_text_file.gz
Note that
ā-pā can require up to twice the time for
decompression, because it performs two decompression
processes: the usual one, and another one that is performed
in advance
of the usual and which is the one that
detects errors, marks them, and finds new entry points to
end/begin the decompression circumventing the problems.
Note also that these
corrupted-gzip-files
should be
always decompressed with ā-pā parameter, even if
a āgztoolā index file exists for them, because
the index file stores entry points, but does not store where
do errors occur in the āgzipā file. That said,
if the ā-[bL]ā point of extraction is beyond the
point(s) of error in the āgzipā file and an
index file exists, then the decompression can proceed fine
without ā-pā, as the index points stored in the
index file are always clean.
* When tailing an still-growing gzip file (ā-Tā) that could contain errors at some point, one may still want to obtain output from the gzip stream as soon as possible - this is what the patching option ā-Pā is for (like ā-pā but capitalized): with ā-pā āgztoolā decompress the stream about 48 kiB ahead of the output that is actually shown/written in order to catch possible gzip-stream errors ahead of output, and so maintain always a clean output without error-introduced artifacts. This has the side effect that output must always wait for that 48 kiB of data to be available in advance, which if the file grows slowly can take a very long time. With ā-Pā the buffer-ahead restriction is relaxed to just as few bytes as available before reaching end-of-file and waiting for new data, so responsiveness is as quick as without ā-pā. The side effect of ā-Pā is that depending on the gzip file some errors may lead to incorrect output being shown/written - though in this case a " PATCHING WARNING " would be shown (to stderr).
$Ā gztoolĀ -PTĀ application_log.gz
The same applies to ā-Sā though in this case thereās no output, as only the index is being constructed:
$Ā gztoolĀ -PSĀ application_log.gz
* To tail to stdout, like a ātail -fā, an still-growing gzip file (an index file will be created with name āstill-growing-gzip-file.gziā in this case):
$Ā gztoolĀ -TĀ still-growing-gzip-file.gz
* More on files still being "Supervised" (ā-Sā) by another āgztoolā instance: they can also be tailed Ć la ātail -fā without updating the index on disk using ā-Wā:
$Ā gztoolĀ -WTĀ still-growing-gzip-file.gz
* Compress (ā-cā) an still growing (ā-Eā) file: in this case both āstill-growing-file.gzā and āstill-growing-file.gziā files will be created on-the-fly as the source file grows. Note that in order to terminate compression, Ctrl+C must be used to kill gztool: this results in an incomplete-gzip-file as per GZIP standard, but this is not important as it will contain all the source data, and both āgzipā and āgztoolā (or any other tool) can correctly and completely decompress it:
$Ā gztoolĀ -EcĀ still-growing-file
* If you have an incomplete index file (it just does not have the length of the source data, as it didnāt correctly finish) and want to make it complete and so that the length of the uncompressed data be stored, just unconditionally complete it with ā-Cā with a new ā-iā run over your gzip file: note that as the existent index data is used (in this case the file āmy-incomplete-gzip-data.gziā), only last compressed bytes are decompressed to complete this action:
$Ā gztoolĀ -CiĀ my-incomplete-gzip-data.gz
* Decompress a file like with gzip (ā-dā), but do not delete (ā-Dā) the original one: Decompressed file will be āmyfileā. Note that gzipped file must have a ".gz" extension or āgztoolā will complain:
$Ā gztoolĀ -DdĀ myfile.gz
* Decompress a file that does not have ".gz" file extension, like with gzip (ā-dā):
$Ā catĀ mycompressedfileĀ |Ā gztoolĀ -dĀ >Ā my_uncompressed_file
* Show internals of all index files in this directory. ā-eā is used not to stop the process on the first error, if a ā*.gziā file is not a valid gzip index file. The ā-llā list option repetition will show data about each index point. ā-lllā also decompress each pointās window to ensure index integrity:
$Ā gztoolĀ -ellĀ *.gzi
If
āgztoolā finds the gzip file companion of the
index file, some statistics are shown, like the index/gzip
size ratio, or the ratio of compression of the gzip file.
Also, if the gzip is complete, the size of the uncompressed
data is shown. This number is interesting if the gzip file
is bigger than 4 GiB, in which case āgunzip -lā
cannot correctly calculate it as it is limited to a 32 bit
counter (see //tools.ietf.org/html/rfc1952#page-5), or if
the gzip file is in ābgzipā format, in which
case āgunzip -lā would only show data about the
first block (< 64 kiB).
Note that āgztool -lā tries to guess the
companion gzip file of the index looking for a file with the
same name, but without the āiā of the
ā.gziā file name extension, or without the
ā.gziā. But the gzip file name can also be
directly indicated with this format:
$Ā gztoolĀ -lĀ -IĀ index_filenameĀ gzip_filename
In this latter case only a pair of index+gzip filenames can be indicated with each use.
* Use a truncated gzip file (100000 first bytes are removed: (not zeroed, removed); if theyāre zeroed cautions are the same, but ā-nā is not needed), to extract from byte 20 MiB, using a previously generated index : as far as the ā-bā parameter refers to a byte after an index point (See ā-llā) and ā-nā be less than that needed first index point, this is always possible. In this case -I gzip_filename.gzi is implicit:
$Ā gztoolĀ -nĀ 100001Ā -bĀ 20MĀ gzip_filename.gz
Take into
account that, as shown, the first byte of the truncated
āgzip_filename.gzā file is numbered
100001
, that is, the bytes retain the order number in
which they appear in the original file (thatās the
reason why it is not the
1
byte).
Please, note that index point positions at index file
may
require also the previous byte
to be available in the
truncated gzip file, as gzip stream is not byte-rounded but
a stream of pure bits. Thus
if youāre thinking on
truncating a gzip file, please do it always at least by one
byte before the indicated index point in the gzip
- as
said, it may not be needed, but in 7 of 8 cases it is
needed.
Another option is to use ā-Zā when
creating the index, as indicated below.
* Create an index for a gzip file in which every index entry point is adjusted to byte boundary, so no previous byte (bits) is needed. Note that in general the byte at which the index entry point begins does not represent a clear cut point as the gzip window needs up to 7 bits from the previous byte. This is so because gzip is a bit-level stream compressor. With ā-Zā the cut point is always clean and no bits from the previous byte are required. This will result in index points spaced by more than ā-sā bytes between then, and so, may be, less points in the index. But this is completely safe and sound.
$ gztool -Z my_gzip_file.gz
ā-Zā exists since gztool v1.6.0 .
* Since v1.5.0, using ā-[fW]ā (ā-fā: force index overwriting; ā-Wā: do not write index) with ā-[ST]ā (ā-Sā: create index on still-growing gzip file; ā-Tā: tail and continue decompressing to stdout) indicates āgztoolā to continue operations even after the source file is overwritten. If using ā-fā, the index file will be overwritten. For example:
$Ā gztoolĀ -WTĀ log_filename.gz
...
FileĀ overwritingĀ detectedĀ andĀ restartingĀ decompression...
ProcessingĀ ālog_filename.gzā
...
INTERNALS
By default gzip-compressed files cannot be accessed in random mode: any byte required at position N requires the complete gzip file to be decompressed from the beginning to the N byte. Nonetheless Mark Adler, the author of zlib (//github.com/madler/zlib), provided years ago a cryptic file named āzran.cā (//github.com/madler/zlib/blob/master/examples/zran.c) that creates an "index" of "windows" filled with 32 kiB of uncompressed data at different positions along the un/compressed file, which can be used to initialize the zlib library and make it behave as if compressed data begin there.
gztool builds upon zran.c to provide a useful command line tool. Also, some optimizations has been made:
* gztool can correctly read incomplete gzip-concatenated-files (using ā-pā), that is, a gzip composed of a concatenation of āgzipā files, some of which are not correctly terminated. This can happen, for example, when using rsyslogās veryRobustZip omfile option (//www.rsyslog.com/doc/v8-stable/configuration/modules/omfile.html#veryrobustzip) and the process that is logging is abruptly terminated and then restarted.
* gztool can store line numbering information in the index (use only if source data is text!), and retrieve data from a specific line number using ā-Lā. (Using ā-[xXz]ā when creating the index selects Unix new line format (default), old Mac new line format, or no line information respectively.)
* gztool can Supervise an still-growing gzip file (for example, a log created by rsyslog directly in gzip format) and generate the index on-the-fly, thus reducing in the practice to zero the time of index creation. See ā-Sā.
* extraction of data and index creation are interleaved, so thereās no waste of time for the index creation.
* index files are reusable , so they can be stopped at any time and reused and/or completed later.
* an ex novo index file format has been created to store the index
* span between index points is raised by default from 1 MiB to 10 MiB, and can be adjusted with ā-sā ( span ).
* windows are compressed in file
* windows are not loaded in memory unless theyāre needed, so the application memory footprint is fairly low (< 1 MiB)
* gztool can compress files (ā-cā) and at the same time generate an index that is about 10-100 times smaller than if the index is generated after the file has already been compressed with gzip.
* Compatible with ābgzipā files (//www.htslib.org/doc/bgzip.html)
* Compatible with complete āgzipā concatenated files
* Compatible with rsyslogās veryRobustZip omfile option (variable-short-uncompressed complete-gzip-block sizes)
* data can be provided from/to stdin/stdout
* gztool can be used to remotely retrieve just a small part of a bigger gzip compressed file and successfully decompress it locally. See //unix.stackexchange.com/questions/429197/#541903 . Just note that the gztool index file must be also available.
PROJECT HOME PAGE
//github.com/circulosmeos/gztool
SEE ALSO
gzip (1), gunzip (1), zlib (3)
AUTHOR
This program was written by Roberto S. Galende <roberto.s.galende@gmail.com> on work by Mark Adlerās zlib (examples/zran.c) and is copyrighted under zlib licence terms.