Iva*_*ang 2 linux bash shell-script
我对 shell 脚本知之甚少,但不幸的是我必须编写一个。我想问一下bash脚本迭代移动文件,我需要移动按月排序的日志文件,这些文件将由cronjob执行。计划是将 mtime +30(1 个月前)文件移动到几个文件夹中,cronjob 将每天执行,例如:
/home/Work/LogFiles/20131200012.log
/home/Work/LogFiles/thisLogIsDifferent.log
/home/Work/LogFiles/20120322222.log
/home/Work/LogFiles/20140100011.log
/home/Work/LogFiles/thisLogIsDifferent2.log
Run Code Online (Sandbox Code Playgroud)
/home/Work/LogFiles/thisLogIsDifferent.log
/home/Work/LogFiles/thisLogIsDifferent2.log
/home/Work/LogFiles/2013/DEC/20131200012.log
/home/Work/LogFiles/2012/MAR/20120322222.log
/home/Work/LogFiles/2014/JAN/20140100011.log
Run Code Online (Sandbox Code Playgroud)
我对我必须使用的方法一无所知。所以这是我糟糕的 shell 脚本:
BASE_DIR=/home/Work/LogFiles
REPORT_DIR_YEAR=$BASE_DIR/`date +%Y`
REPORT_DIR=$REPORT_DIR_YEAR/`date +%b`
NOW=$(date +"%Y%m")
if ! [ -d $REPORT_DIR_YEAR ]; then
mkdir $REPORT_DIR_YEAR
if ! [ -d $REPORT_DIR ]; then
mkdir $REPORT_DIR
fi
fi
#THIS PART NEED TO BE RE-ARRANGED
#What I expect is not date=NOW; BUT SOME KIND LIKE date %m-1? but I still don't have any ideas about modify date function.
for file in find $BASE_DIR -maxdepth 1 -type f -mtime +30 -name '*$NOW*'
do
month=$(ls -l $file | awk '{ print $6 }')
case "$month" in
"Jan") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Feb") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Mar") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Apr") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"May") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Jun") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Jul") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Aug") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Sep") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Oct") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Nov") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
"Dec") mv $file $REPORT_DIR_YEAR/$month/$file echo "$file moved to $REPORT_DIR/$file";;
*) echo " Do nothing " ;;
esac
done
Run Code Online (Sandbox Code Playgroud)
是的,这种情况$month
不适用于之前的 for 循环$file
。为什么?我不知道。我只是从各种来源、论坛、for 循环中的示例中复制,但它不起作用。
首先,解析 的输出绝不是一个好主意,ls
因为它会导致各种问题。获取文件年龄的更好方法是stat
. 例如:
$ ls -l 20120322222.log
-rw-r--r-- 1 terdon terdon 0 Jan 1 2012 20120322222.log
$ stat -c %y 20120322222.log
2012-01-01 00:00:00.000000000 +0100
Run Code Online (Sandbox Code Playgroud)
所以,现在我们知道如何获取文件的年龄,问题是如何将其转换为三个字母的月份名称。最简单的是使用date
:
$ date -d "2012-01-01" +"%b"
Jan
Run Code Online (Sandbox Code Playgroud)
结合这两个命令给出:
$ date -d "$(stat -c %y 20120322222.log)" +"%b"
Jan
Run Code Online (Sandbox Code Playgroud)
因此,考虑到这一点,您可以将脚本编写为:
#!/usr/bin/env bash
BASE_DIR=/home/Work/LogFiles
## Find those files that are older than a month
find "$BASE_DIR" -maxdepth 1 -mtime +30 -type f -name "20*" |
while IFS= read -r file; do
## Get the file's modification year
year="$(date -d "$(stat -c %y "$file")" +%Y)"
## Get the file's modification month
month="$(date -d "$(stat -c %y "$file")" +%b)"
## Create the directories if they don't exist. The -p flag
## makes 'mkdir' create the parent directories as needed so
## you don't need to create $year explicitly.
[[ ! -d "$BASE_DIR/$year/$month" ]] && mkdir -p "$BASE_DIR/$year/$month";
## Move the file
mv "$file" "$BASE_DIR/$year/$month"
done
Run Code Online (Sandbox Code Playgroud)
上面的脚本假设您想获得文件的真实修改日期,而不是解析名称。如果您想解析名称,请告诉我,我会相应地进行修改。
归档时间: |
|
查看次数: |
16502 次 |
最近记录: |