前言
这几天一直在处理shell脚本,作为服务器开发人员免不了要部署一些环境,数据备份和同步工作也是家常便饭,最近常搞的几个命令有 find
、rsync
、sed
等,之前也写过一篇 《linux环境下使用rsync命令完成数据同步》,不过这次有新的需求了。
插曲
前段时间发现通过 rysnc
同步游戏版本数据时,在数据同步前有一个较长的等待时间,大概12G数据需要等待4分钟,多方面查找原因后定位到应该是 rsync
的 -c
参数导致的,参数全称是 --checksum
打开校验开关,强制对文件传输进行校验,多次实验后发现只要把 -c
参数省略,这个检验所花的4分钟就能省掉,同步前校验只会根据修改的时间戳和文件大小来判断,这在大多数情况下足够了。
根据时间段同步
现在想同步日志文件,因为日志文件是每小时产生一个,之前的日志文件绝大多数情况也不会改动,所以再同步时没必要检测所有的日志文件,只需要同步最近一段时间的就可以了,这样可以减少文件比对的时间。
查询了 sync
命令的所有参数,没有找到指定同步时间段的参数,但是有个 --files-from=FILE
看起来能实现这个需求,man手册中是这样写的:
1 | Using this option allows you to specify the exact list of files to transfer (as read from the specified FILE or - for standard input). It also tweaks the default behavior of rsync to make transferring just the specified files and directories easier: |
基于参数的描述,我只要提供一个包含指定时间段的待同步的所有文件名的文件就可以了,比如将指定时间段需要同步的文件名放到 /tmp/foo
文件中,然后以 --files-from=/tmp/foo
形式来指定就行了。
其实还有一个方便的写法,就是直接在参数后面利用 find
写过滤文件的命令,比如只同步最近3天修改过的文件就可以写成:
1 | rsync -avz --files-from=<(find /var/log/ -mtime -3) /usr remote:/backup |
其中 find /var/log/ -mtime -3
命令的含义就是找出 /var/log/
目录下最近3天修改的文件。
按时间过滤文件
有了上面的基础命令,想要同步不同时间段的文件只需要修改 find
命令参数就可以了,比较常用的参数就是 mtime
了。
使用 mtime 参数查找
mtime 表示文件的修改时间,用在 find
查找时是以天为单位的,最小间隔24小时,数字是几就表示几天前,带有 +
表示几天前之外,带有 -
表示今天前之内,下面举几个例子:
- 查找修改时间在3天之前的文件(修改时间距今大于96小时)
1 | find /var/log/ -mtime +3 |
- 查找修改时间在3天之内的文件(修改时间距今小于72小时)
1 | find /var/log/ -mtime -3 |
- 查找修改时间在3天前当天的文件(修改时间距今大于72小时,小于96小时)
1 | find /var/log/ -mtime 3 |
如果对mtime参数的使用有点疑惑,可以看一下下面的示意图:
除了上面提到的 -mtime
参数,还有类似的 -atime
和 -ctime
参数,这三个参数的含义如下,使用时可根据定义来选择:
1 | -atime:文件访问时间,文件被读取或执行的时间。 |
使用 newermt 进行更精确查找
find -newermt
的通用形式是find -newerXY reference,目的是找到一些X属性比variable的Y属性更早的文件,其中X代表find的目标文件属性,Y代表参照属性。X可选a,c,m,Y可选a,c,m,t,其中t代表客观绝对时间,只作为参照属性存在,具体详细的用法参照man手册:
1 | -newerXY reference |
如果要找到修改时间在2023-3-18 20:00:00 和 2023-3-18 22:00:00 之间的文件可以写成:
1 | find /var/log -newermt '2023-3-18 20:00:00' ! -newermt '2023-3-18 22:00:00' |
总结
rsync
命令本身不能指定同步的时间段,可搭配find
命令来同步指定时间段的文件rsync -avz --files-from=<(find /var/log/ -mtime -3) /usr remote:/backup
同步修改时间在3天内的文件- 使用
newermt
可按时间精确查找,形式如find /var/log -newermt '2023-3-18 20:00:00' ! -newermt '2023-3-18 22:00:00'
- 假设变量 KEY=birthday、FILE=myfile.log,查找KEY所在的行号可以使用
grep -rn $KEY" $FILE | awk -F ':' '{print $1}'
- 还是在上面的假设
sed -n '/${KEY}=/' $FILE
无法获得行号,使用sed -n '/birthday=/' $FILE
就可以 - 上面这种sed命令中使用变量不生效的问题目前还没找到解决方法,有解决方案的大佬请指教
- 不过
sed -e "${LINE},${LINE}s%$OLD_VAL%$NEW_VAL%g" $FILE
这种替换命令就支持变量,但sed不支持非贪婪模式,目前有点迷糊,还在探索中
不要规划孩子必须在哪一个领域取得成就,但只要她喜欢,就提供一个舞台,让她尽情去发挥~
2023-3-19 21:01:51