我是bash的新手,所以我在为此提出正确的语法时遇到了一些麻烦。但要点是我需要遍历某个目录中的所有文件并打印文件名中日期和时间的未来。
Filename语法如下:
2016-04-27_19EST-KST.txt
2016-04-28_02EST-MSK.txt
2016-04-28_03EST-CET.txt
2016-04-28_09EST-EST.txt
2016-04-28_10EST-CST.txt
2016-04-28_12EST-PST.txt
一天中的小时是军事格式,我不关心最后一个" EST-CST"部分。
这是我到目前为止所得到的:
#!/bin/bash
curdate=$(date +%Y-%m-%d)
curtime=$(date +%H)
for fn in *.txt;do
[ "${curdate}_${curtime}*.txt" "<" "$fn" ] && continue
echo "$fn"
done
这只返回目录中的所有文件。我在这里做错了什么?
答案 0 :(得分:1)
此脚本将打印所有名称代表比当前日期更新的日期的文件:
#!/bin/bash
d="$(date +%Y-%m-%d_%HZZZ.tmp.txt)"
touch "$d"
printf "%s\n" *.txt | LC_ALL=C sort | awk -v d="$d" 'f{print} d==$0{f=1}'
rm "$d"
d="$(date +%Y-%m-%d_%HZZZ.tmp.txt)"
这会创建一个与当前时间匹配的名称。
touch "$d"
这将创建一个名称与当前时间匹配的文件。
printf "%s\n" *.txt
这会将所有*.txt
个文件名(每行一个)打印到stdout。
(您的文件都有合理的名称。如果有任何名称中有换行符,那么我们希望用空格分隔的列表替换这个换行符分隔的列表,并对下面的代码进行适当的更改。)
LC_ALL=C sort
这会将文件名按顺序排序。我指定LC_ALL=C
,以确保订单符合预期。
此时,请注意我们在临时文件名中使用的ZZZ
。这可以确保临时文件在具有当前文件的任何其他文件之后排序
小时。如果我们想在输出中包含当前小时的文件,我们可能会改为使用AAA
。
awk -v d="$d" 'f{print} d==$0{f=1}'
此代码打印我们的临时文件后的所有文件名与当前时间。
rm "$d"
这将删除不再需要的临时文件。
如果上面的脚本正在中断,它会在目录中留下一个迷路文件。例如,如果在脚本运行时按下Ctrl-C,则可能会发生这种情况。为确保始终删除该文件,我们可以使用trap
:
#!/bin/bash
d="$(date +%Y-%m-%d_%HZZZ.tmp.txt)"
trap 'rm "$d"' EXIT
touch "$d"
printf "%s\n" *.txt | LC_ALL=C sort | awk -v d="$d" 'f{print} d==$0{f=1}'
答案 1 :(得分:1)
您的解决方案已接近但最好使用数字比较来比较日期并使用date
标准化日期表示,例如:
#!/bin/bash
curdate=$(date +%Y%m%d%H)
for fn in *.txt; do
tmp=${fn%%EST*} # remove timezone info, ignored
fdate=$(date -d "${tmp/_/ }" +%Y%m%d%H)
(( curdate < fdate )) && echo "$fn"
done
答案 2 :(得分:1)
在某些时候,您可能需要使用awk或sed或其他东西来解析日期。你可以尝试这样的事情:
#!/bin/bash
curdate=$(date +%Y-%m-%d)
curtime=$(date +%H)
for fn in *.txt;do
date=$(echo $fn | sed 's/EST.*.txt//')
if [[ "${curdate}_${curtime}" < "$date" ]]; then
echo $fn
fi
done
注意:请记住sed命令非常具体。这仅在文件名始终采用您发布的格式时才有效。您可以根据自己的需要进行调整。