Linux 压缩、解压缩和文件切割的学习笔记
目录
Linux 压缩、解压缩和文件切割的学习笔记
Linux 中有许多压缩和解压的命令,有些是针对文件进行压缩,有些用于目录的归档及压缩。其中,只能用于文件压缩和解压的命令有:compress, uncompress, gzip, gunzip, bzip2, bunzip2, xz, xunzip。可以用于打包归档的有:zip, unzip, tar, cpio。用于分隔打包文件的命令有:split。
备注:以下命令的帮助文档是依据 CentOS 8.5 获取的。
单文件的压缩和解压缩
compress 和 uncompress
该工具比较古老,压缩比不高,现在不常用。如果需要安装 ncompress 包。
yum provides compress
yum install -y ncompress
rpm -ql ncompress
/usr/bin/compress
/usr/bin/uncompress
......
格式和常用选项:
compress [options] [file...]
-f 不会提示覆盖现存的文件
-d 解压缩,相当于 uncompress
-c 将结果输出至标准输出,不改变原文件
-r 递归操作目录
-v 显示详情
compress 压缩后,每个文件都会替换成追加扩展名为 .Z 压缩后的文件,保留原始文件的所有者模式、访问和修改时间。如果没有指定文件,则从标准输入读入被压缩后至标准输出。注意,符号链接文件不会被压缩。如果一个文件有多个硬链接,则该命令会拒绝压缩,除非使用 -f 选项。
示例:压缩和解压缩
compress file
ls
file.Z
uncompress file.Z
# 希望保留原文件的方法
compress -c file > file.z
直接查看压缩文件的文本内容,zcat 相等于 uncompress -c:
zcat file.Z
gzip、gunzip 和 zcat
gzip 将压缩指定文件的大小。每个文件都会被带扩展名为 .gz 的文件代替,同时保留原有的属主属组模式、访问和修改时间。如果没有指定文件,或文件名是 “-”,则标准输入压缩至标准输出。该命令只会试图压缩普通文件。也不会压缩符号链接文件。
目前,gunzip 能够解压由 gzip, zip, compress, compress -H 或 pack 压缩的文件。
zcat 相当于 gunzip -c 。
格式:
gzip [option]... FILE...
常用选项:
| 选项 | 说明 |
|---|---|
| -d, --decompress, --uncompress | 解压缩,相当于 gunzip |
| -c, --stdout, --to-stdout | 结果输出至标准输出,保留原文件不变 |
| -f, --force | 强制压缩或解压缩,即使文件有多个连接或对应文件已经存在,或者,如果被压缩的数据读自或写入到终端。 |
| -#, --fast, --best | 指定压缩比,# 取值为 1~9,默认是 6,–fast 等价于 -1,–best 等价于 -9。 |
| -k, --keep | 在压缩或解压过程中,保留输入文件 |
| -l, --list | 对每个压缩的文件,列出以下字段:压缩后大小,解压后大小,压缩比,解压后名称 |
| -n, --no-name | 在压缩时,默认不会保存原有文件名和时间戳(文件名被截断的例外)。解压时,如果原有文件名和时间戳存在,不会恢复以上两项。该选项在解压时默认的。 |
| -N, --name | 在压缩时,始终保存原有文件名和时间戳,这是默认的。在解压时,恢复原有文件名和时间戳。 |
| -q, --quiet | 压制所有警告 |
| -r, --recursive | 递归经过目录结构 |
| -S .suf, --suffix .suf | 当压缩时,使用 .suf 后缀,而不是 .gz。 |
| –synchronous | 使用同步输出。 |
| -t, --test | 测试 |
| –rsynable | 当在两台电脑上同步压缩文件时,该选项允许仅仅远程同步传输改变改的文件,而不是整个归档文件。 |
示例:
cat messages | gzip > m.gz
# 如果有多个文件可以这样使用
cat file1 file2 | gzip > foo.gz
# 这种方法比以下方法好
gzip -c file1 file2 > foo.gz
# 如果你想重新压缩合并的文件以得到更好的压缩
gzip -cd old.gz | gzip > new.gz
bzip2、bunzip2、bzcat 和 bzip2recover
可能需要安装该包
# dnf install -y bzip2
# 该包带有的命令不少
# rpm -ql bzip2
/usr/bin/bunzip2
/usr/bin/bzcat
/usr/bin/bzcmp
/usr/bin/bzdiff
/usr/bin/bzegrep
/usr/bin/bzfgrep
/usr/bin/bzgrep
/usr/bin/bzip2
/usr/bin/bzip2recover
/usr/bin/bzless
/usr/bin/bzmore
......
命令的作用:
bzip2, bunzip2 # 一个块排序的文件压缩工具
bzcat # 解压缩文件到标准输出
bzip2recover # 从损坏的bzip2文件中恢复数据
bzip2 # 的命令行选项故意与 `gzip` 的非常相似,但是它们并不相同。
bzip2 选项:
| 选项 | 说明 |
|---|---|
| -c, --stdout | 压缩或解压到标准输出 |
| -d, -decompress | 强制解压。bzip2, bunzip2 和 bzcat 其实是同一个程序,根据名称来决定做那个动作。该标志覆盖这个机制,强制其去解压 |
| -z, --compress | 与 -d 相反,强制压缩,不管调用那个命令名称 |
| -t, --test | 测试指定文件的完整性,不会解压。 |
| -f, --force | 强制输出文件的覆盖 |
| -k, --keep | 在压缩和解压时保留原文件 |
| -s, --small | 在使用压缩、解压和测试中,减少内存的使用。 |
| -q, --quiet | 压制非必要的警告信息。但是有关 I/O 错误和其他关键信息不会被压制 |
| -v, --verbose | 详细模式,如果 -vv,则更详细 |
| -1, --fast to -9, --best | 在压缩时,设置块大小为 100k, 200k, … 900k。 |
| – | 把后续的参数都当成文件名,即使以 - 开头的参数。 |
xz、unxz 和 xzcat
xz是一个通用数据压缩工具,命令行语法类似于gzip和bzip2。
语法:
xz [option...] [file...]
unxz 等价于 xz --decompress
xzcat 等价于 xz --decompress --stdout
一些特殊情况:
除非输出至标准输出,否则,xz 遇到以下情况时会显示警告并跳过文件 file:
- 文件不是普通文件。符号链接文件不认为是普通文件。
- 文件有多余一个硬链接。
- 文件有 setuid, setgid, 或 sticky 位设置。
- 压缩时 file 文件已经具有目标文件格式的,例如,file.xz。
- 解压时 file 文件没有支持的文件格式。
操作模式
| 选项 | 说明 |
|---|---|
| -z, --compress | 压缩。当没有指定操作模式,这是默认的操作模式。 |
| -d, --decompress, --uncompress | 解压缩。 |
| -t, --test | 测试被压缩的文件的完整性。 |
| -l, --list | 打印压缩文件的信息。 |
操作修饰符
| 选项 | 说明 |
|---|---|
| -k, --keep | 不删除输入的原始文件 |
| -f, --force | 该选项有几种效果:1. 如果目标文件已经存在,则覆盖。2. 如果输入文件是软连接文件、有多个硬链接文件、有 setuid, setgid, stiky 位的设置的可以压缩。但是这些位不会被拷贝。3. 在使用 --decompress --stdout ,且 xz 不能设别的文件仅仅输出标准输出。 |
| -c, --stdout, --to-stdout | 把压缩或解压文件输出至屏幕 |
| -S .suf, --suffix=.suf | 压缩时使用 .suf 当成后缀,而不是 .xz |
| –files[=file] | 从文件中读取要处理的文件名 |
压缩选项
| 选项 | 说明 |
|---|---|
| -C check, --check=check | 指定整体性检测类型。可以有:none, crc32, crc64, sha356 |
| -0 … -9 | 选择一个压缩预设的级别。默认是 -6。 |
| –memlimit-compress=limit | 设置一个压缩时使用内存的限制值 |
| –memlimit-decompress=limit | 设置一个解压缩时使用内存的限制值 |
| -M limit, --memlimit=limit, --memory=limit | 这等价于指定以上两个选项。 |
| -T threads, --threads=threads | 指定使用时工作线程数量 |
目录打包和压缩
zip
这是个打包和压缩(归档)文件的工具,适用于各种系统。类似于Unix的 tar 和 compress 的组合。
如果想要打包某个目录下的内容,而不包括该目录本身,需要先进入该目录,如果使用以下命令:
cd xxx
zip -r /data/data.zip *
命令格式。基本的命令格式如下:
zip options archive inpath inpath ...
其中 archive 是一个新的或已存的 zip 归档文件,inpath 是可以包含通配符的目录或文件路径。当提供了一个已存的 zip 归档文件,那么,zip 将替换zip归档文件中的相同名称条目(匹配已经保存的相对名称),或者为新的文件新增条目。
示例:
例如,foo.zip 存在,且包含 foo.file1 和 foo/file2,而 foo 目录中有文件 foo/file1 和 foo/file3,那么:
zip -r foo.zip foo
# 更简洁地
zip -r foo foo
foo.zip 中 foo/file1 被替换,foo/file3 会新增。执行之后,foo.zip 包含三个文件,其中 foo/file2 没有变化。
-@ file lists
如果将文件列表指定给 -@(不适合 MacOS),那么,zip 将从标准输入读取输入文件列表,而不是从命令行上读取。例如,
zip -@ foo
将会存储标准输入中列出的每行一个的文件到 foo.zip 中。
在Unix中,该选项可以在与 find 命令联合中发挥显著效果。例如,想要归档当前目录及其子目录中的所有 C 源文件:
find . -name "*.[ch]" -print | zip source -@
注意,模式必须引用以防止被shell扩展它。
Streaming input and output 流输入和输出
zip 也会接受字符(-)作为zip文件名,这样就会把zip文件写入标准输出中,从而允许通过管道把输出送到另一个程序中。例如:
zip -r - . | dd of=/dev/nrst0 obs=16k
将zip输出直接写入具有指定块大小的磁带,以便备份当前目录。
zip 也接受字符(-)作为要被压缩的文件名,这样就会从标准输入读取文件,从而允许zip从另一个程序中获取输入。例如:
tar cf - . | zip backup -
将会压缩来自 tar 命令的输出,已实现对当前目录进行备份的目的。这通常比前一个使用 -r 选项的示例产生更好的压缩,因为 zip 能利用两个文件之间的冗余。使用以下命令能恢复备份:
unzip -p backup | tar xf -
如果没有提供 zip 文件名,且输出的也不是终端,则 zip 当作过滤器,压缩标准输入到标准输出。例如:
tar cf - . | zip | dd of=/dev/nrst0 obs=16k
等价于:
tar cf - . | zip - - | dd of=/dev/nrst0 obs=16k
以这种方式创建的 zip 归档文件可以被由 unzip 包提供的程序 funzip ,或被由 gzip 包提供的程序 gunzip 提取(如果 zip 使用了 Zip64 扩展,则以下 gunzip 可能不支持该操作)。例如:
dd if=/dev/nrst0 ibs=16k | funzip | tar xvf -
该流可以保存到一个文件,也使用了 unzip 。
命令模式 。zip 现在支持两种不同类型的命令模式,即外部的和内部的。外部模式包括 add, update, freshen ,它们读自文件系统(也可从现有归档)的文件,而外部模式包括 delete and copy ,它们只能操作现有归档中的条目。
| 命令模式 | 说明 |
|---|---|
| add | 更新现有条目且新增新的文件。如果归档文件不存在则创建它。这是模式的模式。 |
| update (-u) | 如果文件系统上的文件更新一些则更新现有归档,且新增新文件。如果归档不存在,则提示警告,然后创建新的归档。 |
| freshen (-f) | 如果文件系统的文件更新一些,则更新归档中的现有条目。不会新增新文件进去。 |
| delete (-d) | 在现有归档中选择条目并删除它们。 |
| copy (-U) | 在现有归档中选择条目并拷贝到新的归档中。 |
tar
tar(Tape ARchive)磁带归档之意。可以对文件或目录进行打包及压缩,能够保留原有的文件属性,常用于备份。
格式:
# 传统格式,在选项前面无需使用"-"
tar {A|c|d|r|t|u|x} [option...] [arg...]
示例:
tar -cf avchive.tar foo bar # Create archive.tar from foo and bar.
tar -tvf archive.tar # List all files in archive.tar verbosely.
tar -xf archive # Extract all files from archive.tar.
几个主要的操作及选项
c 创建
t 列出,for tell
x 解包
v 详细信息
f 指定打包的文件
-C 指定解压到那个目录
示例:
tar xvf archive.tar -C /data
如果想要在打包的同时进行压缩可以使用压缩命令:
z # for gzip
j # for bz2
J # for xz
示例:
tar zcvf archive.tar.gz foo/
tar jcvf archive.tar.bz2 foo/
tar Jcvf archive.tar.xz foo/
压缩功能是调用对应的命令,如果系统上没有安装对应的命令,就不能正常使用了。
使用角度看,使用 xz 压缩的速度明显慢,但是压缩后的大小也没有明显的差异。可以考虑使用 bz2 or gzip 。
在使用 tar 进行解包时,无需指定对应压缩的选项,直接使用以下格式即可:
tar xf archive.tar.gz -C /tmp
对于文件或目录具有 acl 属性的,如果按照以上的操作,是不能保留该属性的。
对于这些扩展的文件属性,需要指定以下选项:
--acls # 启用ACLs支持
--xattrs # 启用扩展的属性支持
--selinux # 启用SELinux上下文支持
可以使用以下方法进行复制:
tar c /dat/ | tar x -C /tmp
可以使用 --exclude 来排除文件:
tar zcvf /data/archive.tgz --exclude=/app/host1 --exclude=/app/host2 /app
可以使用 -T 选项指定输入的文件,-X 选项指定要排除的文件列表
tar zcvf bak.tgz -T /tar_list.txt -X /exclude_list.txt
cpio
cpio 是历史悠久的打包和解压工具,目前使用较少,但是在一些文件中使用,例如,CentOS 6 中的 initramfs-2.6.32-754.el6.x86_64.img 就是使用这个命令生成的。
这个文件可以先用以下命令来查看文件的格式:
file initramfs-2.6.32-754.el6.x86_64.img
initramfs-2.6.32-754.el6.x86_64.img: gzip compressed data, ...
# 如果想要解压缩,要进行文件名修改
mv initramfs-2.6.32-754.el6.x86_64.img initramfs-2.6.32-754.el6.x86_64.img.gz
# gzip -d initramfs-2.6.32-754.el6.x86_64.img.gz
# 解压后查看文件格式
file initramfs-2.6.32-754.el6.x86_64.img
initramfs-2.6.32-754.el6.x86_64.img: ASCII cpio archive (SVR4 with no CRC)
cpio 命令是通过重定向的方式将打包备份,还原恢复的工具。它可以解压以 “.cpio” 或 “.tar” 结尾的文件。
格式:
cpio [option] > filename | devname
cpio [option] < filename | devname
常用选项:
-o output 模式(以内存为参照),即打包,将从标准输入的文件打包至标准输出
-i input 模式,即解包,将从标准输入的打包文件解压至当前目录
-t 预览,查看标准输入传入的打包文件输出至标准输出
-O filename 输出至指定的归档文件名
-A 向已存在的归档文件中追加文件
-I filename 对指定的归档文件解压
-F filename 使用指定的文件名替代标准输入或输出
-d 解压生成目录,即在cpio解压时,能自动生成需要的目录
-v 显示打包过程中的文件名称
示例:
# 将 etc 目录进行备份
find ./etc -print | cpio -ov > etc.bak.cpio
# 将 /data 目录追加到 etc.bak.cpio
find /data | cpio -oA -F etc.bak.cpio
# 预览内容
cpio -tv < etc.bak.cpio
# 解压文件
cpio -idv < etc.bak.cpio
注意:不要使用绝对路径进行打包,否则解包时会覆盖原有的内容,比较危险。建议先进入对应的目录后使用相对路径。
用于分隔文件
split 分割
split 命令可以用于分割一个大文件为多个小文件。
格式:
split [OPTION] ... [FILE [PREFIX]]
描述:
输出 FILE 的片段至 PREFIXaa, PREFIXab, …;默认大小为 1000 行,且默认前缀PREFIX是 ‘x’。
如果没有指定文件FILE,或 FILE 是 -,则从标准输入中读取。
| 选项 | 说明 |
|---|---|
| -a, --suffix-length=N | 生成后缀的长度 N (默认是 2) |
| –additional-suffix=SUFFIX | 追加额外的 SUFFIX 至文件名后面 |
| -b, --bytes=SIZE | 每个输出文件大小为 SIZE 字节 |
| -C, --line-bytes=SIZE | 每个输出文件最多放置SIZE字节大小的记录 |
| -d | 使用从0开始的数字后缀,而不是字符的后缀 |
| –numeric-suffixes[=FROM] | 与 -d 相同,不过允许设置开始的值 |
| -x | 使用从0开始的十六进制的后缀 |
| –hex-suffixes[=FROM] | 与 -x 相同,只不过允许设置开始的值 |
| -e, --elide-empty-files | 与 -n 一起时,不要生成空的输出文件 |
| –filter=COMMAND | 写入 shell COMMAND 中,文件名是 $FILE |
| -l, --lines=NUMBER | 每个文件放置 NUMBER 行/记录 |
| -n, --number=CHUNKS | 生成 CHUNKS 个输出文件 |
| -t, --separator=SEP | 使用 SEP 当成记录的分隔符,而不是换行符;'\0’指定 NUL 字符 |
| -u, --unbuffered | 使用 ‘-n r/…’,立即拷贝输入到输出 |
| –verbose | 在每个输出文件打开前,打印诊断信息 |
示例:
# 分隔大的打包文件成多个大小为 1M 的文件
split -b 1M archive.tar.gz archive.tar.gz
ll -h
-rw-r--r-- 1 root root 1.0M Apr 6 12:00 archive.tar.gzaa
-rw-r--r-- 1 root root 1.0M Apr 6 12:00 archive.tar.gzab
-rw-r--r-- 1 root root 1.0M Apr 6 12:00 archive.tar.gzac
-rw-r--r-- 1 root root 730K Apr 6 12:00 archive.tar.gzad
# 分隔成多个以数字后缀的文件
split -b 1M archive.tar.gz archive.tar.gz.part
ll -h
-rw-r--r-- 1 root root 1.0M Apr 6 12:00 archive.tar.gz01
-rw-r--r-- 1 root root 1.0M Apr 6 12:00 archive.tar.gz02
-rw-r--r-- 1 root root 1.0M Apr 6 12:00 archive.tar.gz03
-rw-r--r-- 1 root root 730K Apr 6 12:00 archive.tar.gz04
# 将多个切割后的小文件合并成一个大文件
cat archive.tar.gz.part* > archive.tar.gz