2010-10-07 3 views
0

У меня есть папки с именованием:имени Анализировать папки в Баше

yearmonthday_jobcode_descriptor

т.е. 20101007_GR1234_Whatsit

Я пытаюсь написать скрипт, который делает несколько вещей:

  • перемещать любые папки, в которых дата старше, чем $ X. ./old
  • перемещать любые папки, в которых установлена ​​дата в будущем ./old
  • перемещать любые папки, которые DonT соответствуют конвенции ./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 

Я могу обрабатывать все зацикливание, моя главная задача на данный момент, как извлечь имена папок в переменные, которые могут быть сопоставлены для дат. Текущее текущее регулярное выражение просто проверяет соответствие конвенции.

+1

Это своего рода задачи, для которых я никогда бы не использовать Баш ... если у меня есть Perl в рука. – leonbloy

ответ

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 
2
$ foo="20101007_GR1234_Whatsit" 
$ echo ${foo%%_*} 
20101007 
3

Вы можете использовать команду Вырезать, чтобы разметить строку (-d задает разделитель, -f указывает, какое поле вы хотите сохранить) -

echo 20101007_GR1234_Whatsit | cut -d'_' -f1 

дает

20101007 

Оттуда вы можете использовать команду date для анализа даты-

foo=`date -d 20101007 +%s` 

преобразует строку даты в эпоху (секунды с 1 января 1970 г.), которую затем можно легко сравнить.

Если вы не хотите возиться со временем эпохи, вы можете назвать дату несколько раз, чтобы разобрать различные части -

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

но это сделает ваши сравнения немного более сложным.

+0

Спасибо, это был ответ, который я нашел наиболее полезным. Выполнив это и отметив мое окончательное решение в качестве ответа. – jhogendorn

+0

+1 Для описания команды cut – Elpezmuerto

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)){ 
     .............. 
    } 
}' 
Смежные вопросы