我正在使用下面的脚本将超过一天的文件移动到其他目录,我只是用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
不过效果不错。
我在原剧本中遗漏的确切逻辑是什么?
您的脚本的工作假设是第一个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。(如果你不能做到这一点,你将从外壳中得到非常令人困惑的行为,因为空格不再分隔单词…)
PS:你知道每次新的月份开始时你的脚本都会失败吗?
PPS:你知道你的脚本依赖于当前的语言环境吗?在我的电脑上,每年的这个时候,行中的第7个单词是"Dez",所以我在运行脚本时必须添加一个LANG=C
。
刚刚看到您的更新
$i | ...
将尝试运行一个可执行文件,无论$i
的值是多少,它都会被调用。在您的情况下,这将适用于$i=1、2和3(但不能执行您希望的操作),否则将失败。
您希望将字符串发送到管道中的下一个进程,而不是运行该名称的可执行文件。你需要做
echo $i | ...
我给出的答案是出于一般目的。我知道你有一天要求只移动旧文件,但这个解决方案根据给定的标准移动当前目录中的文件。Shell脚本采用以下参数-出于一般目的,我将包含shell脚本的sh文件命名为";mymov";
- 第一个参数可以是-O或-N。使用-O,会移动超过指定日期的文件。使用-N,会移动比指定日期更新的文件
- 第二个参数是日期,格式为dd/mm/yyyy。将移动比此日期旧或新的文件(取决于第一个参数)
- 第三个参数是当前目录中移动文件的文件夹的名称。如果此文件夹不存在,则会创建此文件夹
Shell脚本mymov只移动文件,不移动文件夹。移动文件后,shell脚本还会显示移动的文件总数和当前目录中存在的文件总数。
示例:c: \ABC>mymov-O 2015年8月5日XYZ将当前目录(即c:\ABC)中早于2015年8月5日的文件移到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