0040. shell命令--gzip

目录

40. shell命令--gzip

功能说明

语法格式

选项说明

实践操作


40. shell命令--gzip

功能说明

        gzip 是一种广泛使用的压缩程序,它使用 Lempel-Ziv 编码(LZ77)和 Huffman 编码的组合来减小文件大小。gzip 主要用于 Unix 和类 Unix 系统(如 Linux)上压缩和解压缩文件。压缩后的文件通常以 .gz 作为文件扩展名。

        gzip 是在 Linux 系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用。gzip 不仅可以用来压缩大的、较少使用的文件以节省磁盘空间,还可以和 tar 命令一起构成 Linux 操作系统中比较流行的压缩文件格式。据统计,gzip 命令对文本文件有60%~70%的压缩率。减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。

语法格式

gzip [选项] 文件名

SYNOPSIS
       gzip [ -acdfhlLnNrtvV19 ] [-S suffix] [ name ...  ]
       gunzip [ -acfhlLnNrtvV ] [-S suffix] [ name ...  ]
       zcat [ -fhLV ] [ name ...  ]

选项说明

-a或--ascii  使用ASCII文字模式。
-c或--stdout或--to-stdout  把压缩后的文件输出到标准输出设备,不去更动原始文件。
-d或--decompress或----uncompress  解开压缩文件。
-f或--force  强行压缩文件。不理会文件名称或硬连接是否存在以及该文件是否为符号连接。
-h或--help  在线帮助。
-l或--list  列出压缩文件的相关信息。
-L或--license  显示版本与版权信息。
-n或--no-name  压缩文件时,不保存原来的文件名称及时间戳记。
-N或--name  压缩文件时,保存原来的文件名称及时间戳记。
-q或--quiet  不显示警告信息。
-r或--recursive  递归处理,将指定目录下的所有文件及子目录一并处理。
-S<压缩字尾字符串>或----suffix<压缩字尾字符串>  更改压缩字尾字符串。
-t或--test  测试压缩文件是否正确无误。
-v或--verbose  显示指令执行过程。
-V或--version  显示版本信息。
-<压缩效率><num> 压缩效率是一个介于1-9的数值,预设值为"6",指定愈大的数值,压缩效率就会愈高。
-num 用指定的数字num调整压缩的速度,-1或--fast表示最快压缩方法(低压缩比),-9或--best表示最慢压缩方法(高压缩比)。系统缺省值为6。
--best  此参数的效果和指定"-9"参数相同。
--fast  此参数的效果和指定"-1"参数相同。

实践操作

0. 环境准备
mkdir -p /test/gzip
cd /test/gzip
yes test |head -c 30M >30M_file1.txt
mkdir -p dir1/test{1..3}

1. 直接压缩文件
ls -lh
gzip 30M_file1.txt    #会删除原始文件
ls -lh

2. 查看压缩文件相关信息
ls -lh
gzip -l 30M_file1.txt

3. 解压缩文件
ls -lh
cp 30M_file1.txt.gz{,.bak}
gzip -d 30M_file1.txt.gz    #会删除压缩文件
ls -lh
mv 30M_file1.txt.gz.bak 30M_file1.txt.gz
rm -rf 30M_file1.txt
ls -lh
gunzip 30M_file1.txt.gz     #也可以解压,也会删除压缩文件
ls -lh

4. 保留原始文件并压缩
ls -lh 
gzip -c 30M_file1.txt    #把压缩后的文件输出到标准输出设备
gzip -c 30M_file1.txt >30M_file1.txt.gz    #重定向到文件中
ls -lh

5. 查看压缩文件内的内容
gzip -dc 30M_file1.txt.gz | less    
zcat 30M_file1.txt.gz | wc -l    #使用zcat也可以查看

6. 使用 tar 与 gzip 结合压缩目录
#当需要压缩整个目录时,gzip 本身并不支持直接压缩目录。但可以通过与 tar 命令结合来实现这一功能。
# tar 命令可以将多个文件和目录打包成一个文件,然后再使用 gzip 进行压缩
ls
tar cf - dir1/ |gzip > dir1-1.tar.gz    #这种方法比较麻烦
ll
tar tf dir1-1.tar.gz
tar zcf dir1-2.tar.gz dir1    #直接使用 tar -z 参数调用 gizp 程序压缩文件
tar tf dir1-2.tar.gz

7. 其它拓展
7.1 使用 pigz 提高压缩速度
#对于需要处理大量数据或希望加快压缩速度的场景,pigz 是一个很好的选择。
# pigz 是 gzip 的并行版本,能够利用多核 CPU 的优势来加速压缩和解压缩过程。
ls
mv * dir1
yum provides pigz
yum install -y pigz
yes test |head -c 2G >2G_file.txt
ls -lh
ulimit -u    #查看当前用户可以开启的最大线程数
pigz -p 4 2G_file.txt
ls -lh
#这里,-p 4 选项告诉 pigz 使用 4 个线程来压缩 myfile.txt。
#通过调整线程数,可以根据系统的 CPU 核心数来优化性能。

7.2 使用 xz 替代 gzip 以获得更高压缩率
#尽管 gzip 提供了不错的压缩率和速度,但如果你需要更高的压缩率,xz 是一个更好的选择。
#xz 使用 LZMA 算法,通常能提供比 gzip 更高的压缩率,但相应地,压缩和解压缩的速度会慢一些。
ls -lh
gzip -d 2G_file.txt.gz
ls -lh
xz 2G_file.txt    #压缩
ls -lh
unxz 2G_file.txt.xz    #解压,也可以使用xz -d
ls -lh
rm -rf 2G_file.txt

<think>嗯,用户需要处理/log目录下从20170606到20170612的日志文件,按天打包压缩,并删除源文件。首先,我得确定如何提取日期部分。文件名里有类似base.log.2017-06-06.3152这样的结构,日期格式是YYYY-MM-DD。所以需要从文件名中提取出日期部分,比如2017-06-06。 接下来,应该遍历这些文件,按日期分类。可以用awk或者cut来分割文件名,提取日期。例如,用awk分割点号,第三个字段就是日期。或者用cut -d '.' -f3。不过要注意文件名中的其他部分是否有干扰,比如可能有多个点号的情况。 然后,需要为每个唯一的日期创建一个压缩包,把对应日期的文件加进去。这里可以用循环,先收集所有日期,去重,再逐个处理。比如用ls列出所有文件,提取日期,用sort -u去重,然后循环每个日期,打包该日期的所有文件。 打包时使用tar命令,参数czf创建gzip压缩的文件,比如log.2017-06-06.tar.gz。打包完成后删除源文件,用rm -f确保删除。需要注意的是,如果文件名中有空格或其他特殊字符,要处理好引号,避免解析错误。 另外,用户给出的例子中有文件名存在空格,比如“base. log.2017-06-10.747”,中间有个空格,这可能是个打字错误,但在实际处理中可能需要处理这种情况,或者用户提供的文件名是否真的存在这样的问题。这时候可能需要更稳健的文件名处理方式,比如使用find命令加上-print0来处理带空格的文件名,但可能会增加脚本复杂度。 还要考虑日期范围,用户需要的是20170606到20170612,但给出的例子中有2017-06-13的文件,是否需要排除?用户的问题描述里说“现需要将这些文件按天打包压缩”,可能是指所有文件,但例子中可能包含超出范围的日期,需要根据实际情况判断是否需要过滤日期范围。如果确实需要限定日期范围,应该在提取日期后,进行日期比较,只处理在指定范围内的日期。 不过用户的问题描述中并没有明确提到需要过滤日期,只是说目录下有从20170606到20170612的文件,可能意味着只需要处理这些日期。但实际脚本可能需要先提取所有文件的日期,然后处理所有存在的日期,不管是否在范围内,或者需要检查日期是否在指定范围内。需要进一步确认用户的需求,但根据问题描述,可能不需要特别过滤,只是按文件实际存在的日期打包。 另外,处理文件时,是否要包括所有以base.log开头的文件?比如例子中的base.log.2017-06-06.3152和base.log.2017-06-06.5312,这些文件都属于同一天,应该被打包到同一个tar.gz文件中。所以需要正确匹配这些文件。 最后,删除源文件需要在打包成功之后进行,避免打包过程中出错导致文件丢失。所以在tar命令成功执行后,再删除对应的文件。可以使用&&操作符,即tar成功则执行rm。 综上,脚本的大致步骤是: 1. 遍历/log目录下的所有符合条件的日志文件。 2. 提取每个文件的日期部分。 3. 收集所有唯一的日期。 4. 对每个日期,打包该日期对应的所有文件,压缩为log.日期.tar.gz。 5. 删除已打包的文件。 可能的陷阱包括文件名中的空格、日期提取错误、打包时遗漏文件或包含多余文件,以及处理大量文件时的性能问题。需要测试脚本,确保正确处理各种情况。</think>以下是一个实现按天打包压缩日志文件并删除源文件的Shell脚本解决方案,包含详细步骤说明: --- ### **一、需求分析** 目标:将`/log`目录下形如`base.log.2017-06-06.xxxx`的文件按日期打包为`log.2017-06-06.tar.gz`,并删除源文件。 --- ### **二、分步骤实现** #### **1. 提取所有日期并去重** ```bash #!/bin/bash LOG_DIR="/log" # 获取所有唯一日期(格式:YYYY-MM-DD) dates=$(ls "$LOG_DIR" | grep -oE '20[0-9]{2}-[0-9]{2}-[0-9]{2}' | sort -u) ``` #### **2. 遍历日期进行打包** ```bash for date in $dates; do # 构造目标压缩文件名 archive="log.${date}.tar.gz" # 查找该日期所有文件(精确匹配日期段) files=$(find "$LOG_DIR" -name "base.log.${date}.*") # 打包并压缩 if [ -n "$files" ]; then echo "正在打包 $date 的日志..." tar czf "${LOG_DIR}/${archive}" $files # 删除源文件(仅在打包成功后执行) if [ $? -eq 0 ]; then rm -f $files echo "$date 文件已压缩并删除源文件" else echo "$date 打包失败,保留源文件" fi fi done ``` --- ### **三、完整脚本** ```bash #!/bin/bash LOG_DIR="/log" # 获取所有唯一日期(格式:YYYY-MM-DD) dates=$(ls "$LOG_DIR" | grep -oE '20[0-9]{2}-[0-9]{2}-[0-9]{2}' | sort -u) for date in $dates; do archive="${LOG_DIR}/log.${date}.tar.gz" files=$(find "$LOG_DIR" -name "base.log.${date}.*") if [ -n "$files" ]; then echo "打包: $date" tar czf "$archive" $files if [ $? -eq 0 ]; then rm -f $files echo "成功: ${archive} 已创建,源文件已删除" else echo "错误: ${date} 打包失败" fi else echo "警告: 未找到 $date 的日志文件" fi done ``` --- ### **四、关键点解析** 1. **日期提取** - 使用正则表达式`grep -oE '20[0-9]{2}-[0-9]{2}-[0-9]{2}'`精确匹配日期格式 - `sort -u`去重避免重复处理 2. **文件匹配** - `find "$LOG_DIR" -name "base.log.${date}.*"`确保精确匹配目标日期的所有文件 3. **错误处理** - `$? -eq 0`检查`tar`命令是否执行成功 - 仅在打包成功后删除源文件(`rm -f $files`) --- ### **五、注意事项** 1. **权限问题** 确保脚本有权限操作`/log`目录,建议提前测试: ```bash chmod +x pack_logs.sh # 添加执行权限 ./pack_logs.sh # 测试运行 ``` 2. **文件名规范** 如果日志文件名包含空格,需要修改`find`命令为: ```bash find "$LOG_DIR" -name "base.log.${date}.*" -print0 | xargs -0 tar czf "$archive" ``` 3. **日期范围过滤(可选)** 如果需要限制为2017-06-06到2017-06-12: ```bash start_date="2017-06-06" end_date="2017-06-12" dates=$(ls "$LOG_DIR" | grep -oE '20[0-9]{2}-[0-9]{2}-[0-9]{2}' | sort -u | awk -v s="$start_date" -v e="$end_date" '$0 >= s && $0 <= e') ``` --- ### **六、扩展改进建议** 1. **日志记录** 添加日志记录功能: ```bash exec >> "${LOG_DIR}/pack.log" 2>&1 # 重定向输出到日志文件 ``` 2. **定时任务** 通过`crontab`每日自动执行: ```bash 0 2 * * * /path/to/pack_logs.sh # 每天凌晨2点执行 ``` --- 通过这个脚本,可以实现对日志文件的自动化按天归档管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MineGi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值