Linux 在bash中解析文件夹名称

Linux 在bash中解析文件夹名称,linux,bash,grep,Linux,Bash,Grep,我有命名约定的文件夹: yearmonthday\u作业代码\u描述符 ie 20101007_GR1234_Whatsit 我正在尝试编写一个脚本,它可以完成以下几件事: 将日期早于$X的任何文件夹移动到。/old 移动日期在将来的任何文件夹。/old 移动任何不符合约定的文件夹。/old 删除./old中日期早于$X+$Y的所有文件夹 这是我当前的循环,正如您所看到的,我的bash脚本相当平庸 #!/bin/bash for file in $1/*; do if [ -d $f

我有命名约定的文件夹:

yearmonthday\u作业代码\u描述符

ie 20101007_GR1234_Whatsit

我正在尝试编写一个脚本,它可以完成以下几件事:

  • 将日期早于$X的任何文件夹移动到。/old
  • 移动日期在将来的任何文件夹。/old
  • 移动任何不符合约定的文件夹。/old
  • 删除./old中日期早于$X+$Y的所有文件夹
这是我当前的循环,正如您所看到的,我的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

我可以处理所有的循环,目前我主要关心的是如何将文件夹名称提取到可以比较日期的变量中。上面的当前正则表达式只是检查是否符合约定。

您可以使用cut命令标记字符串(-d指定分隔符,-f指定要保留的字段)-

$ foo="20101007_GR1234_Whatsit"
$ echo ${foo%%_*}
20101007
给予

从那里,您可以使用date命令来解析日期-

foo=`date -d 20101007 +%s`
将日期字符串转换为历元时间(自1970年1月1日起的秒数),然后可以轻松比较

如果不想弄乱历元时间,可以多次调用date来解析不同的部分-

 day=`date -d 20101007 +%d`
 month=`date -d 20101007 +%m`
 year=`date -d 20101007 +%Y`

但这会使比较变得更复杂。

您可以使用cut命令标记字符串(-d指定分隔符,-f指定要保留的字段)-

#!/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) ){
        ..............
   }
}'
给予

从那里,您可以使用date命令来解析日期-

foo=`date -d 20101007 +%s`
将日期字符串转换为历元时间(自1970年1月1日起的秒数),然后可以轻松比较

如果不想弄乱历元时间,可以多次调用date来解析不同的部分-

 day=`date -d 20101007 +%d`
 month=`date -d 20101007 +%m`
 year=`date -d 20101007 +%Y`
但这会让你的比较变得更复杂。

#/bin/bash
#!/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) ){
        ..............
   }
}'
开始{ x=mktime(“2010 10 08 00”)#在这里设置x,不管它是什么 y=mktime(“2010 10 02 00”)#在此处设置y,无论是什么 olddir=“/tmp/old” } { yr=substr($0,1,4)#获得年份 mth=substr($0,5,2)#获得月份 day=substr($0,7,2)#获得一天 t=mktime(年“月”日“00”)#转换为秒进行比较 如果(t<0){print“格式错误:$0;next} 如果(t>x){ 打印$0”晚于X:“X” }否则{ 打印“将“$0”移动到旧” cmd=“mv$0”oldir 打印命令 #系统(cmd)#取消注释以执行实际移动 } 如果(t>(x+y)){ .............. } }'
#/bin/bash
开始{
x=mktime(“2010 10 08 00”)#在这里设置x,不管它是什么
y=mktime(“2010 10 02 00”)#在此处设置y,无论是什么
olddir=“/tmp/old”
}
{
yr=substr($0,1,4)#获得年份
mth=substr($0,5,2)#获得月份
day=substr($0,7,2)#获得一天
t=mktime(年“月”日“00”)#转换为秒进行比较
如果(t<0){print“格式错误:$0;next}
如果(t>x){
打印$0”晚于X:“X”
}否则{
打印“将“$0”移动到旧”
cmd=“mv$0”oldir
打印命令
#系统(cmd)#取消注释以执行实际移动
}
如果(t>(x+y)){
..............
}
}'

这是我的最终解决方案,适用于将来尝试这样做的任何人:

#!/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
#/bin/bash
ARCHIVE=“old”
NOW=`date+%s`
宽限期=$((60*60*24*7*2))
截止日期=$($现在-$宽限期))
截止日期=$($截止日期-$宽限期))
函数getos{
UNAME=`UNAME`
平台=“未知”
如果[[“$UNAME”=='Linux']];则
echo“linux”
elif[“$UNAME”==='Darwin']];然后
回声“osx”
其他的
echo“linux”
fi
}
函数日期时间戳{
DATE=“$1”
OS=`getos`
TIMESTAMP='empty'
如果[[“$OS”==“linux”];则
时间戳=`date-d$date+%s`
elif[“$OS”=='osx']];然后
时间戳=`date-j-f“%Y%m%d”“$date”“+%s”`
fi
echo$时间戳
}
函数移动到存档{
ITEM=“$1”
如果[!-d“$ARCHIVE”];则
mkdir$ARCHIVE
fi
文件夹=`date+%Y%m%d“`
如果[!-d“$ARCHIVE/$FOLDER”];则
mkdir$ARCHIVE/$FOLDER
fi
mv$ITEM$ARCHIVE/$FOLDER/$ITEM
}
函数deletefromarchive{
ITEM=“$1”
WD=`pwd`
匹配=$(echo$WD | grep-oE“*?/$WORKING\u DIR/$ARCHIVE$”)
如果[-n“$MATCH”];则
rm-rf$项目;
fi
}
工作目录=“1美元”;
cd“$WORKING_DIR”
以*存档;做
如果[-d$file];然后
如果[“$file”!=“$ARCHIVE”];然后
MATCH=$(echo$file | grep-oE“[0-9]{8}-[A-Z]*[0-9]*-?*”)
如果[-z“$MATCH”];然后
移动到存档$file
其他的
日期=$(echo$文件| cut-d'-'-f1);
TIMESTAMP=`dateToTimestamp$DATE`
如果[[“$TIMESTAMP”>“$NOW”]];然后
移动到存档$file
elif[“$TIMESTAMP”<“$CUTOFF”]];然后
移动到存档$file
fi
fi
fi
fi
完成
cd$存档
以*存档;做
如果[-d$file];然后
MATCH=$(echo$file | grep-oE“^[0-9]{8}$”)
如果[-z“$MATCH”];然后
deletefromarchive$文件
其他的
TIMESTAMP=`dateToTimestamp$文件`
如果[[“$TIMESTAMP”>“$NOW”]];然后
deletefromarchive$文件
elif[“$TIMESTAMP”<“$DETAILED”];然后
deletefromarchive$文件
fi
fi
fi
完成

这是我的最终解决方案,适用于将来尝试这样做的任何人:

#!/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
#/bin/bash
ARCHIVE=“old”
NOW=`date+%s`
宽限期=$((60*60*24*7*2))
截止日期=$($现在-$宽限期))
截止日期=$($截止日期-$宽限期))
函数getos{
UNAME=`UNAME`
平台=“未知”
如果[[“$UNAME”=='Linux']];则
echo“linux”
elif[“$UNAME”==='Darwin']];然后
回声“osx”
其他的
echo“linux”
fi
}
函数日期时间戳{
DATE=“$1”
OS=`getos`
TIMESTAMP='empty'
如果[[“$OS”=='linux']];