【问题标题】:Bash script that move files from one directory with lots of files to a month folder将文件从一个包含大量文件的目录移动到一个月文件夹的 Bash 脚本
【发布时间】:2013-07-06 23:07:43
【问题描述】:

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

例子:

文件创建于:

May 15 testmay.txt
Jun 10 testjun.txt
Jul 01 testjul.txt

它们应该在那些目录中

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

我已经有了这个来将远程服务器中的文件同步到临时月份目录。

#!/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

我怎样才能完成这个脚本?

【问题讨论】:

  • 您能否更明确地说明您希望接下来发生的事情?只需用文字一步一步地解释您想要发生的事情。
  • 正如您在脚本中看到的,我将大量文件捕获到 tmp 目录,现在 tmp 目录包含数千个文件。我希望现在整理这些文件: - 在特定月份创建的文件应移动到为该月创建的目录。
  • 看起来这种情况已经发生了……$LOGDIR/$JAAR-$MAAND/ 不是特定月份和年份的目录吗?
  • 是的,但是在我获取文件的地方,/opt/logs/sessions/,有很多来自不同月份的文件。所以它会复制它们,但不会根据创建日期对它们进行排序。
  • 您将如何确定创建日期?您是在文件中搜索,还是按时间戳搜索?另外,您会在 $LOGDIR/$JAAR-$MAAND/ 下创建更多的日期目录吗?我很困惑为什么要将所有文件复制到以单个日期命名的目录中,而不是将它们复制到 $LOGDIR/tmp 之类的目录中。

标签: bash date directory mv file-structure


【解决方案1】:

我只是需要做一些类似的事情,并想出了一个我认为非常巧妙的方法。我在一个目录中有超过 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_* 可变时间范围(到最近的月份)内的每个文件,这将根据其mtime 将其归档到适当的$DST/YYYY-MM.zip 文件。

如果您使用的是早于 4.3.3 的 find 版本,请参阅 this page 以了解如何使用 -newer 而不是 -newermt 的示例,您只需在主循环中执行此操作.

【讨论】:

    【解决方案2】:

    这样的?

    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
    

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

    【讨论】:

      【解决方案3】:

      如果你放

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

      写入一个名为archive的脚本文件,例如可以执行

      archive *
      

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

      /bin/ls | xargs archive
      

      相反。 (如果要谨慎,可以使用mv -i选项。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多