0

我正在使用下面的脚本将超过一天的文件移动到其他目录,我只是用一个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

它工作正常。

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

4

3 回答 3

2

您的脚本基于第一个 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在运行脚本时添加一个。

于 2012-12-17T00:00:44.873 回答
0

刚看到你的更新

$i | ...

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

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

echo $i | ...
于 2012-12-16T14:33:12.067 回答
0

我给出的答案是通用的。我知道您要求仅在一天前移动文件,但此解决方案根据给定标准移动当前目录中的文件。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
于 2022-02-15T15:31:56.183 回答