我有使用命名约定的文件夹:
yearmonthday_jobcode_descriptor
即20101007_GR1234_Whatsit
我正在尝试编写一个执行以下操作的脚本:
这是我当前的循环,因为你可以看到我的bash脚本非常平庸。
#!/bin/bash
for file in $1/*; do
if [ -d $file ]; then
echo $(echo $file | grep -oE "[0-9]{8}_[A-Z]*[0-9]*_?.*")
fi
done
我可以处理所有循环,目前我主要关心的是如何将文件夹名称提取到可以比较日期的变量中。上面的当前正则表达式只是检查是否符合约定。
答案 0 :(得分:4)
您可以使用cut命令来标记字符串(-d指定分隔符,-f指定要保留的字段) -
echo 20101007_GR1234_Whatsit | cut -d'_' -f1
给出
20101007
从那里,您可以使用date命令来解析日期 -
foo=`date -d 20101007 +%s`
会将日期字符串转换为纪元时间(自1970年1月1日起的秒数),然后可以轻松比较。
如果你不想搞乱纪元时间,你可以多次调用日期来解析不同的部分 -
day=`date -d 20101007 +%d`
month=`date -d 20101007 +%m`
year=`date -d 20101007 +%Y`
但它会使你的比较更加复杂。
答案 1 :(得分:2)
$ foo="20101007_GR1234_Whatsit"
$ echo ${foo%%_*}
20101007
答案 2 :(得分:1)
#!/bin/bash
ls -d ????????_[A-Z][A-Z]*_* | awk 'BEGIN{
x=mktime("2010 10 08 00 00 00") # set your X here, whatever it is
y=mktime("2010 10 02 00 00 00") # set your Y here, whatever it is
olddir="/tmp/old"
}
{
yr=substr($0,1,4) # get year
mth=substr($0,5,2) # get month
day=substr($0,7,2) # get day
t= mktime(yr" "mth" "day" 00 00 00") #convert to secs for comparison
if (t < 0) { print "Wrong format: "$0 ;next}
if ( t > x){
print $0 " is later than X: "x
}else{
print "moving "$0" to old"
cmd="mv $0 "oldir
print cmd
#system(cmd) #uncomment to do actual moving
}
if ( t> (x+y) ){
..............
}
}'
答案 3 :(得分:1)
这是我的最终解决方案,适用于将来尝试这样做的任何人:
#!/bin/bash
ARCHIVE="old"
NOW=`date +%s`
GRACE_PERIOD=$((60*60*24*7*2))
CUTOFF=$(($NOW-$GRACE_PERIOD))
DEADLINE=$(($CUTOFF-$GRACE_PERIOD))
function getos {
UNAME=`uname`
PLATFORM="unknown"
if [[ "$UNAME" == 'Linux' ]]; then
echo 'linux'
elif [[ "$UNAME" == 'Darwin' ]]; then
echo 'osx'
else
echo 'linux'
fi
}
function dateToTimestamp {
DATE="$1"
OS=`getos`
TIMESTAMP='empty'
if [[ "$OS" == 'linux' ]]; then
TIMESTAMP=`date -d $DATE +%s`
elif [[ "$OS" == 'osx' ]]; then
TIMESTAMP=`date -j -f "%Y%m%d" "$DATE" "+%s"`
fi
echo $TIMESTAMP
}
function movetoarchive {
ITEM="$1"
if [ ! -d "$ARCHIVE" ]; then
mkdir $ARCHIVE
fi
FOLDER=`date +"%Y%m%d"`
if [ ! -d "$ARCHIVE/$FOLDER" ]; then
mkdir $ARCHIVE/$FOLDER
fi
mv $ITEM $ARCHIVE/$FOLDER/$ITEM
}
function deletefromarchive {
ITEM="$1"
WD=`pwd`
MATCH=$(echo $WD | grep -oE ".*?/$WORKING_DIR/$ARCHIVE$")
if [ -n "$MATCH" ]; then
rm -rf $ITEM;
fi
}
WORKING_DIR="$1";
cd "$WORKING_DIR"
for file in *; do
if [ -d $file ]; then
if [ "$file" != "$ARCHIVE" ]; then
MATCH=$(echo $file | grep -oE "[0-9]{8}-[A-Z]*[0-9]*-?.*")
if [ -z "$MATCH" ]; then
movetoarchive $file
else
DATE=$(echo $file | cut -d'-' -f1);
TIMESTAMP=`dateToTimestamp $DATE`
if [[ "$TIMESTAMP" > "$NOW" ]]; then
movetoarchive $file
elif [[ "$TIMESTAMP" < "$CUTOFF" ]]; then
movetoarchive $file
fi
fi
fi
fi
done
cd $ARCHIVE
for file in *; do
if [ -d $file ]; then
MATCH=$(echo $file | grep -oE "^[0-9]{8}$")
if [ -z "$MATCH" ]; then
deletefromarchive $file
else
TIMESTAMP=`dateToTimestamp $file`
if [[ "$TIMESTAMP" > "$NOW" ]]; then
deletefromarchive $file
elif [[ "$TIMESTAMP" < "$DEADLINE" ]]; then
deletefromarchive $file
fi
fi
fi
done