归档压缩与管道组合:tar、gzip、xargs
tar:打包归档
tar(Tape Archive)最初用于磁带备份,现在是 Linux 标准的归档工具。它把多个文件/目录打包成一个文件,不压缩或配合压缩算法。
# 创建归档(-c create, -v verbose, -f file)
tar -cvf archive.tar file1 file2 dir/
# 解压归档(-x extract)
tar -xvf archive.tar
# 查看归档内容(-t list)
tar -tvf archive.tar
# 追加文件到归档(-r append)
tar -rvf archive.tar newfile.txt
# 从归档中删除文件(--delete)
tar --delete -f archive.tar file1.txt
常用选项
| 选项 | 作用 | 记忆 |
|---|---|---|
-c | 创建归档 | create |
-x | 解压归档 | extract |
-t | 列出内容 | table of contents |
-v | 显示过程 | verbose |
-f | 指定文件名 | file |
-r | 追加文件 | replace/append |
-C | 切换到指定目录 | Change directory |
-p | 保留权限 | preserve |
gzip / gunzip:压缩解压
gzip 使用 DEFLATE 算法压缩单个文件,压缩后原文件被替换为 .gz 文件。
# 压缩文件(原文件被替换为 file.txt.gz)
gzip file.txt
# 解压文件(file.txt.gz 被替换为 file.txt)
gunzip file.txt.gz
# 或
gzip -d file.txt.gz
# 压缩时保留原文件(-k keep,部分系统支持)
gzip -k file.txt
# 查看压缩文件信息(-l list)
gzip -l file.txt.gz
# 压缩率(-v verbose)
gzip -v file.txt
# 指定压缩级别(-1 最快到 -9 最好,默认 -6)
gzip -9 file.txt
gzip 压缩信息解读
$ gzip -l file.txt.gz
compressed uncompressed ratio uncompressed_name
1234 5000 75.3% file.txt
| 字段 | 含义 |
|---|---|
| compressed | 压缩后大小(字节) |
| uncompressed | 原始大小(字节) |
| ratio | 压缩率 |
| uncompressed_name | 原始文件名 |
tar + gzip 组合:压缩归档
实际使用中,tar 和 gzip 几乎总是配合使用,用 -z 选项直接调用 gzip。
# 创建压缩归档(.tar.gz 或 .tgz)
tar -czvf archive.tar.gz dir/
# -c = 创建, -z = gzip 压缩, -v = 显示, -f = 文件名
# 解压压缩归档
tar -xzvf archive.tar.gz
# -x = 解压, -z = gzip 解压, -v = 显示, -f = 文件名
# 查看压缩归档内容(不解压)
tar -tzvf archive.tar.gz
# 解压到指定目录(-C)
tar -xzvf archive.tar.gz -C /tmp/
# 只解压特定文件
tar -xzvf archive.tar.gz path/to/file.txt
常见压缩格式
| 扩展名 | 压缩算法 | tar 选项 | 说明 |
|---|---|---|---|
.tar | 无 | -cvf / -xvf | 仅打包 |
.tar.gz .tgz | gzip | -czvf / -xzvf | 最常用 |
.tar.bz2 .tbz2 | bzip2 | -cjvf / -xjvf | 压缩率更高,更慢 |
.tar.xz .txz | xz | -cJvf / -xJvf | 压缩率最高,最慢 |
.zip | zip | 用 unzip / zip | 跨平台兼容 |
xargs:构建参数列表
xargs(Execute Arguments)从标准输入读取数据,构建命令行参数,解决管道不能直接传参数的问题。
为什么需要 xargs
# 错误:find 的输出直接传给 rm 会失败
find . -name "*.tmp" | rm
# rm: missing operand
# 正确:用 xargs 把输入转为 rm 的参数
find . -name "*.tmp" | xargs rm
# 更安全的写法(处理含空格的文件名)
find . -name "*.tmp" -print0 | xargs -0 rm
xargs 基础用法
# 从管道读取文件名并处理
cat files.txt | xargs rm
# 指定每次处理的参数数量(-n)
cat files.txt | xargs -n 1 rm # 每次只传 1 个文件给 rm
# 指定替换标记(-I {})
cat files.txt | xargs -I {} cp {} /backup/
# 并行执行(-P parallel)
cat urls.txt | xargs -P 4 -I {} curl -O {}
# 从字符串构建参数(echo | xargs)
echo "file1 file2 file3" | xargs ls -lh
# 限制参数长度(-s max-chars)
find . -name "*.txt" | xargs -s 1024 rm
xargs 与 find 的组合
# 查找并删除(-exec 的替代方案)
find . -name "*.tmp" | xargs rm
# 查找并显示详细信息
find . -name "*.log" | xargs ls -lh
# 查找并复制(-I 替换标记)
find . -name "*.conf" | xargs -I {} cp {} /backup/
# 查找并压缩(每行一个参数,-d 指定分隔符)
find . -name "*.log" | xargs -d '\n' gzip
# 处理含空格的文件名(-0 以 null 分隔)
find . -name "*.txt" -print0 | xargs -0 rm
xargs vs -exec 对比
| 特性 | find -exec | find | xargs | |------|-------------|----------------| | 效率 | 低(每个文件执行一次命令) | 高(批量传参,一次执行) | | 处理空格文件名 | {} 自动处理 | 需要 -0 | | 灵活性 | 低 | 高(可配合 sort、grep 等) | | 管道中间处理 | 不支持 | 支持 |
# -exec 效率低(1000 个文件执行 1000 次 rm)
find . -name "*.tmp" -exec rm {} \;
# xargs 效率高(1000 个文件可能只执行 1-2 次 rm)
find . -name "*.tmp" | xargs rm
综合实战
场景 1:备份目录
# 打包压缩家目录(排除缓存和临时文件)
tar -czvf backup-$(date +%Y%m%d).tar.gz \
--exclude='*.tmp' \
--exclude='.cache' \
--exclude='node_modules' \
~/Documents ~/Projects
# 解压到指定目录
tar -xzvf backup-20240115.tar.gz -C /restore/
场景 2:批量处理文件
# 查找所有 .log 文件并压缩
find /var/log -name "*.log" -mtime +7 | xargs gzip
# 查找所有 .txt 文件并统计行数
find . -name "*.txt" | xargs wc -l
# 查找所有 .sh 文件并添加执行权限
find . -name "*.sh" | xargs chmod +x
# 查找所有空文件并删除
find . -type f -empty | xargs rm
场景 3:下载多个文件
# 从 URL 列表并行下载
cat urls.txt | xargs -P 4 -I {} wget {}
# 或
cat urls.txt | xargs -P 4 curl -O
本篇小结
tar:打包归档,-cvf创建,-xvf解压,-tvf查看,-rvf追加tar -czvf/tar -xzvf:tar + gzip 组合,最常用.tar.gz(gzip)、.tar.bz2(bzip2)、.tar.xz(xz)压缩率递增,速度递减gzip/gunzip:压缩/解压单个文件,-l查看压缩信息,-1到-9压缩级别xargs:从标准输入构建命令参数,解决管道不能直接传参的问题find ... | xargs cmd比find -exec效率更高,-I {}替换标记,-0处理空格文件名
动手实践
tar 打包练习:
mkdir -p testdir/{a,b,c} touch testdir/{a,b,c}/file.txt tar -cvf test.tar testdir/ tar -tvf test.tar tar -xvf test.tar -C /tmp/压缩解压练习:
tar -czvf test.tar.gz testdir/ ls -lh test.tar.gz rm -rf testdir tar -xzvf test.tar.gzgzip 练习:
echo "Hello World" > hello.txt gzip hello.txt ls -lh hello.txt.gz gzip -l hello.txt.gz gunzip hello.txt.gz cat hello.txtxargs 练习:
echo "file1 file2" | xargs touch ls file1 file2 find . -name "file*" | xargs ls -lh find . -name "file*" | xargs rm综合练习:
# 备份当前目录的 .md 文件 find . -name "*.md" | tar -czvf md-backup.tar.gz -T - # 查找并压缩 7 天前的日志 find /var/log -name "*.log" -mtime +7 | xargs gzip思考:
tar -czvf中的-在-T -中是什么意思?为什么find ... | tar -czvf archive.tar.gz -T -可以工作?