【问题标题】:moving files older than one day移动超过一天的文件
【发布时间】:2012-12-16 14:13:16
【问题描述】:

我正在使用下面的脚本将超过一天的文件移动到其他目录,我只是用echo 语句检查它是否工作正常。

    for i in `ls -lhrt | grep TRACK`
    do
     for j in `$i | awk '{print $7}'`
     do
      if [[ $j -lt $((`date |  awk '{print $3}'` - 1)) ]];
       then echo $j less than $((`date |  awk '{print $3}'` - 1))
      fi
     done
    done

但是我看到了一些错误并且脚本运行不正常。如果我执行ls -lhrt | grep TRACK | awk '{print $7}',它可以正常工作并返回日期(数字字段)。

如果我像这样修改脚本:

    for i in `ls -lhrt | grep TRACK | awk '{print $7}'`
    do 
     if [[ $i -lt $((`date |  awk '{print $3}'` - 1)) ]]; 
      then echo $i less than $((`date |  awk '{print $3}'` - 1))
     fi
    done

虽然效果很好。

我在原始脚本中遗漏的确切逻辑是什么?

【问题讨论】:

  • 我很确定您可以使用 find-mtime +1-ctime +1 选项来做到这一点。
  • @paul:没错。但我只是想知道这个特定脚本可能有什么问题。谢谢
  • 我不确定您要完成什么,但您的 for j 行正在尝试执行 $i 中的任何内容,并将其输出传递给 awk。我怀疑你打算回显 $i 并将其传递给 awk。

标签: linux shell unix scripting


【解决方案1】:

您的脚本的工作假设是第一个 for 循环 (for i in ...) 在行上迭代,但该假设是错误的。如果您在循环体中添加echo "$i",您将看到它对单词而不是行进行操作。

下一个错误已经被指出并且在该行中

for j in `$i | awk '{print $7}'`

脚本尝试执行变量 $i 的内容。您想在此处添加echo 命令,如下所示:

for j in `echo $i ...

但这当然不能解决您的问题,因为 $i 已经包含单个单词,并且不会有 awk 可以打印的第 7 个单词。

一个简单的解决方案(如果你坚持不使用find)确实是你自己写的:

for i in `ls -lhrt | grep TRACK | awk '{print $7}'`

但如果您希望保留两个循环,您可以在脚本中更改特殊变量 IFS(内部字段分隔符),如下所示:

#!/bin/bash

OIFS="$IFS"
IFS="
"
for i in `ls -lhrt` ; do
  IFS="$OIFS"
  echo ">>$i<<"
  for j in `echo $i|awk '{print $7}'` ; do
    echo ">>$j<<"
  done
done

IFS=" 的行在" 之后不包含任何内容,赋值在下一行以单个" 结束,因此将换行符分配给 IFS 特殊变量。请务必尽快在您的脚本中恢复 IFS。 (如果你不这样做,你会从 shell 得到非常混乱的行为,因为空格不再分隔单词......)

PS:你知道每次新月开始你的脚本都会失败吗?

PPS:您知道您的脚本依赖于当前的语言环境吗?在我的 PC 上,行中的第 7 个单词是“Dez”,因此我必须在运行脚本时添加 LANG=C

【讨论】:

    【解决方案2】:

    刚刚看到你的更新

    $i | ...
    

    将尝试运行一个被调用的可执行文件,无论$i 的值是什么。在您的情况下,这将适用于 $i = 1、2 和 3(但不能按照您的意愿行事),否则会失败。

    您希望将字符串发送到管道中的下一个进程,而不是运行该名称的可执行文件。你需要做的

    echo $i | ...
    

    【讨论】:

    • 没有没有帮助。这不会产生任何输出
    • echo $i 会在找到空间的地方简单地换行。
    【解决方案3】:

    我给出的答案是通用的。我知道您要求仅在一天前移动文件,但此解决方案根据给定标准移动当前目录中的文件。 Shell 脚本采用以下参数 - 出于一般目的,我将包含 shell 脚本的 sh 文件命名为“mymov”

    1. 第一个参数可以是 -O 或 -N。使用 -O,移动早于给定日期的文件。使用 -N,移动比给定日期新的文件。
    2. 第二个参数是日期,格式为 dd/mm/yyyy。比此日期更早或更晚的文件(取决于第一个参数)将被移动。
    3. 第三个参数是当前目录中文件被移动的文件夹的名称。如果该文件夹不存在,则会创建此文件夹。

    Shell 脚本 mymov 只移动文件,不移动文件夹。移动文件后,shell脚本还会显示移动的文件总数和当前目录中存在的文件总数。

    示例: c:\ABC> mymov -O 05/08/2015 XYZ 将当前目录的那些文件,即 c:\ABC 中早于 05/08/2015 的文件移动到存在于 c:\ABC 中的文件夹 XYZ 中。如果该文件夹不存在,则会创建此文件夹。

    #! /bin/bash
    
    instance=""
     
    if [ $1 = "-O" ]
    then
      instance="-gt"
    else 
      instance="-lt"
    fi
    
    arr=$(ls)
    
    inputDate=$2
    dd=${inputDate:0:2}
    mm=${inputDate:3:2}
    yyyy=${inputDate:6:4}
    
    dateQuery=$(date --date=$mm/$dd/$yyyy +'%s')
    filename=`basename $0`
    
    totalFiles=0
    movedFiles=0
    
    if [ -d $3 ]
    then
      echo Directory exists
    else 
      mkdir $3
    fi
    
    for file in $arr
    do
      if [ -d $file ]
      then
        continue
      fi
    
      if [ $file = $filename ]
      then 
        echo Skipped Current File
        continue
      fi
    
      fileFormate=`stat --format=%Y $file`
      if [ $dateQuery $instance $fileFormate ]
      then
    
        mv $file $3
        ((movedFiles++))
        ((totalFiles++))
      else
        ((totalFiles++))
      fi
    done
    
    echo Total number of files moved = $movedFiles
    echo Total number of files present = $totalFiles
    

    【讨论】:

      猜你喜欢
      • 2017-01-30
      • 1970-01-01
      • 2020-08-15
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 2012-03-11
      相关资源
      最近更新 更多