274920831 发表于 2017-12-07 19:46

利用shell脚本将最近三个月的日志按月打包压缩,每月执行一次

for (( n = 1; n <4; n++))
do
Ago_time=`date "+%Y%m" --date="$n month ago"`
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ $filedate -eq $Ago_time ]
then
tar -zcvf /tmp/$Ago_time.tar.gz $filename -C /home/
fi
done
done

我先说下我的逻辑Ago_time是年份加月份,比如说201709 ,201710
然后filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}'),文件列表变量。

filedate=`date "+%Y%m" -r $filename`表示是文件的年份加月份,也是形如201709这种格式

如果filedate 等于 Ago_time
那么将文件打包成以月份为文件的tar.gz包,但是我这个命令有个问题,因为$filename 只是一个文件,而我想把所有的本月的文件一起打包压缩,请问应该如何来写?

再一个问题就是上面的脚本的逻辑是否正确?如果不正确,请各位大侠帮忙改正,非常感谢了!

q1208c 发表于 2017-12-07 23:57

回复 1# 274920831

你的代码中有两个大的问题:
一个是两个循环的顺序反了。
因为你那文件列表与日期无关,所以, 取一次就够了。
你现在这样,至少取了3次。
第二,你是每个文件打了一个包。
你应该把相同年月的文件 cp 到一个 文件中,然后对这个文件夹打包。


其实, 你的代码中的那个按月份的循环是没必要的。
你的目的就是把文件按月份成组打个包。
你只要遍历一下目录下的所有文件,如你的 filelist ,
然后对每个文件执行一下date -r ,并把文件 cp 到相应的文件夹,然后再对文件夹打包就行了。

一个循环就够了。
最多加一个判断,如果等于当前月份就忽略该文件。

274920831 发表于 2017-12-08 11:16

回复 2# q1208c

非常感谢你的提醒,我按照理解,将脚本改成了如下所示:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done



脚本到这一段,都是运行正常:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done


但是到这一段:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

运行的有点问题.

我举个例子:
我现在的所有的文件分为两个月份,分别是201712和201711两个月份

但是到这一段的时候:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

只出现了201712.tar.gz的包,而没有出现201711.tar.gz的包

是否是因为这一段的$filedate并没有获取到上面一段里for循环的$filedate的所有值?

274920831 发表于 2017-12-08 11:17

回复 2# q1208c

非常感谢你的提醒,我按照理解,将脚本改成了如下所示:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done



脚本到这一段,都是运行正常:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done


但是到这一段:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

运行的有点问题.

我举个例子:
我现在的所有的文件分为两个月份,分别是201712和201711两个月份

但是到这一段的时候:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

只出现了201712.tar.gz的包,而没有出现201711.tar.gz的包

是否是因为这一段的$filedate并没有获取到上面一段里for循环的$filedate的所有值?

274920831 发表于 2017-12-08 11:17

回复 2# q1208c

非常感谢你的提醒,我按照理解,将脚本改成了如下所示:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done



脚本到这一段,都是运行正常:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done


但是到这一段:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

运行的有点问题.

我举个例子:
我现在的所有的文件分为两个月份,分别是201712和201711两个月份

但是到这一段的时候:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

只出现了201712.tar.gz的包,而没有出现201711.tar.gz的包

是否是因为这一段的$filedate并没有获取到上面一段里for循环的$filedate的所有值?

274920831 发表于 2017-12-08 11:21

回复 2# q1208c

非常感谢你的提醒,我按照理解,将脚本改成了如下所示:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done



脚本到这一段,都是运行正常:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done


但是到这一段:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

运行的有点问题.

我举个例子:
我现在的所有的文件分为两个月份,分别是201712和201711两个月份

但是到这一段的时候:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

只出现了201712.tar.gz的包,而没有出现201711.tar.gz的包

是否是因为这一段的$filedate并没有获取到上面一段里for循环的$filedate的所有值?

274920831 发表于 2017-12-08 11:22

回复 2# q1208c

非常感谢你的提醒,我按照理解,将脚本改成了如下所示:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done



脚本到这一段,都是运行正常:
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
filedate=`date "+%Y%m" -r $filename`
if [ ! -d $filedate ]
then
mkdir -p $filedate
fi
cp $filename $filedate
done


但是到这一段:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

运行的有点问题.

我举个例子:
我现在的所有的文件分为两个月份,分别是201712和201711两个月份

但是到这一段的时候:
for filenum in $filedate
do
tar -zcvf /tmp/$filenum.tar.gz $filenum
done

只出现了201712.tar.gz的包,而没有出现201711.tar.gz的包

是否是因为这一段的$filedate并没有获取到上面一段里for循环的$filedate的所有值?

274920831 发表于 2017-12-08 11:26

回复 2# q1208c

刚才发帖子的时候,提交回复的时候,报database error,结果提交了四次,四个回复都是一样的内容,只需要查看其中一条即可,谢谢了.

q1208c 发表于 2017-12-09 00:53

回复 7# 274920831

filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
    filedate=`date "+%Y%m" -r $filename`
    if [ ! -d $filedate ]
    then
      mkdir -p $filedate
    fi
    cp $filename $filedate
done

for filenum in $filedate
do
    tar -zcvf /tmp/$filenum.tar.gz $filenum
done
你的 filedate是你执行之后的结果,这个结果永远是最近的一个月。
所以,后面的一段应该重新建个新的文件(目录)列表。


274920831 发表于 2017-12-09 11:57

回复 9# q1208c

非常感谢,今天我对脚本进行了更新,请查看是否正确,主要是实现/var/log下三个月之前的日志文件压缩成按月的tar.gz包后,将它进行删除。
#!/bin/bash
filelist=$(ls -l /var/log|grep "^-"|awk '{print $9}')
for filename in $filelist
do
    filedate=`date "+%Y%m" -r $filename`
    if [ ! -d $filedate ]
    then
      mkdir -p $filedate
    fi
    cp $filename $filedate
done

Documentlist=$(ls -l /var/log|grep "^d"|awk '{print $9}')

for Documentname in $Documentlist
do
   if [ ! -f $Documentname.tar.gz ]
   then
   tar -zcvf /var/log/$Documentname.tar.gz $Documentname
   cp /var/log/$Documentname.tar.gz /tmp
   rm -rf /var/log/$Documentname.tar.gz
   rm -rf /var/log/$Documentname
   fi
done

find /var/log/* -mtime +90|xargs rm -rf


对于其中的这一句cp /var/log/$Documentname.tar.gz /tmp
后期有存储设备的话,我会直接使用scp命令,将它备份至存储上


页: [1] 2
查看完整版本: 利用shell脚本将最近三个月的日志按月打包压缩,每月执行一次