Bash脚本将文件从包含大量文件的目录移动到月份文件夹

时间:2013-07-09 11:03:47

标签: bash date directory mv file-structure

我有一个包含数千个文件的目录。 他们有一个特定的创建日期。 现在我想在特定时间将这些文件存档到特定目录。

示例:

在:

上创建的文件
May 15 testmay.txt
Jun 10 testjun.txt
Jul 01 testjul.txt

他们应该进入那些目录的

/2013-05/testmay.txt
/2013-06/testjun.txt
/2013-06/testjul.txt

我已将此文件从远程服务器rsync到临时月目录。

#!/bin/sh

GAMESERVER=game01
IP=172.1.1.1

JAAR=`date --date='' +%Y`
MAAND=`date --date='' +%m`
DAG=`date --date=''  +%d`
LOGDIR=/opt/archief/$GAMESERVER

if [ ! -e $LOGDIR/$JAAR-$MAAND ]; then
        mkdir $LOGDIR/$JAAR-$MAAND/tmp
        chmod -R 770 $LOGDIR/$JAAR-$MAAND/tmp
fi

rsync -prlt --remove-source-files -e ssh root@$IP:/opt/logs/sessions/ $LOGDIR/$JAAR-$MAAND/tmp

chmod -R 770 $LOGDIR/ -R

如何填写此脚本?

3 个答案:

答案 0 :(得分:4)

我只需要做类似的事情,并提出我认为这是一个非常简洁的方法。我在一个目录中有> 100万个文件,我需要根据它们的mtime存档。我正在使用zip来存档这里的文件,因为我希望它们是压缩的,但也可以从Windows系统轻松访问,但您可以轻松地用简单的mv或任何适合的替换它。

SRC="/path/to/src"  # Where the originals are found
DST="/path/to/dst"  # Where to put the .zip file archives

FIND="find $SRC -maxdepth 1 -type f \( -name \*.tmp -o -name \*.log \)" # Base find command

BOUND_LOWER=$( date -d "-3 years" +%s ) # 3 years ago (because we need somewhere to start)
BOUND_UPPER=$( date -d "-1 years" +%s ) # 1 year ago (because we need to keep recent files where they are)

# Round down the BOUND_LOWER to 1st of that month at midnight to get 1st RANGE_START
RANGE_START=$( date -d $( date -d @$BOUND_LOWER +%Y-%m )-01 +%s )

# Loop over each month finding & zipping files until we hit BOUND_UPPER
while [ $RANGE_START -lt $BOUND_UPPER ]; do
    ARCHIVE_NAME=$( date -d @$RANGE_START +%Y-%m )
    echo "Searching for files from $ARCHIVE_NAME"
    RANGE_END=$( date -d "$( date -d @$RANGE_START ) +1 month" +%s )
    eval "$FIND -newermt @$RANGE_START \! -newermt @$RANGE_END -print0" |
        xargs -r0 zip -Tjm $DST/$ARCHIVE_NAME -@
    echo
    RANGE_START=$RANGE_END
done

对于$SRC中符合$FIND条件并且在$BOUND_*可变时间范围内(到最近的月份)的每个文件,这会将其归档到相应的{{1}基于其mtime的文件。

如果您使用的是早于4.3.3的$DST/YYYY-MM.zip版本,请参阅this page,了解如何使用find代替-newer的示例,只需要在主循环内部进行。

答案 1 :(得分:1)

如果你把

for file
do  dir=/`date +%Y-%m -r$file`
    mkdir -p $dir && mv $file $dir
done

到一个名为archive的脚本文件中,您可以执行例如

archive *

将所有文件移动到所需目录。如果这会产生行太长错误,请执行

/bin/ls | xargs archive

代替。 (如果您需要谨慎,可以使用mv -i选项。)

答案 2 :(得分:0)

这样的事情?

DEBUG=echo
cd ${directory_with_files}
for file in * ; do 
    dest=$(stat -c %y "$file" | head -c 7) 
    mkdir -p $dest
    ${DEBUG} mv -v "$file" $dest/$(echo "$file" | sed -e 's/.* \(.*\)/\1/')
done

免责声明:在您的文件的安全副本中对此进行测试。我不会对任何数据丢失负责; - )