2010-05-12 43 views
2

每天,应用程序会创建一个名为file_YYYYMMDD.csv的文件,其中YYYYMMDD是生产日期。但是有时候这个世代会失败,并且几天没有生成任何文件。按生产日期索引的文件

我想要一个简单的方法在bash或sh脚本中找到最近的文件的文件名,它是在给定的参考日期之前生成的。

典型用法:查找最后生成的文件,无视5月1日之后生成的文件。

感谢您的帮助

+0

你问找到最近的文件名文件名作为一个关闭或作为脚本的一部分? – Casey 2010-05-12 21:40:26

+0

我想将它放入一个变量中,以便在脚本中使用它。我看到了很多实现这个目标的方法,但没有一个很简单。 – caas 2010-05-12 21:49:15

回答

0

这个脚本避免:

  • 在一个循环
  • Parsing ls
  • 使用sed多次在while循环创建一个子shell
  • 处理文件不匹配file_*.csv名图案

这里的脚本:

#!/bin/bash 
while read -r file 
do 
    date=${file#*_} # strip off everything up to and including the underscore 
    date=${date%.*} # strip off the dot and everything after 
    if [[ $date < $1 ]] 
    then 
     break 
    fi 
done < <(find -name "file_*.csv" | sort -r) 

# do something with $file, such as: 
echo "$file" 

编辑:

使用bash> = 3.2,则可以使用正则表达式做到这一点:

#!/bin/bash 
regex='file_([[:digit:]]+).csv' 
while read -r file 
do 
    [[ $file =~ $regex ]] 
    date=${BASH_REMATCH[1]} 
    if [[ $date < $1 ]] 
    then 
     break 
    fi 
done < <(find -name "file_*.csv" | sort -r) 

# do something with $file, such as: 
echo "$file" 
+0

谢谢,也很好。 但我更喜欢使用sed的解决方案,因为它提供了更多的可能性来控制处理哪些文件。例如:有时文件名为'file_YYYYMMDD_test.csv'出现在目录中。 我会尝试混合这两个脚本来添加您提出的其他改进。 谢谢! – caas 2010-05-13 11:32:22

+0

@caas:查看我编辑的使用Bash正则表达式的版本,与'sed'版本类似。 – 2010-05-13 14:05:08

0

试试这个:

#!/bin/bash 

ls -r | while read fn; do 
    date=`echo $fn | sed -e 's/^file_\([0-9]*\)\.csv$/\1/'` || continue 
    if [ $date -lt $1 ]; then 
     echo $fn 
     exit 
    fi 
done 

只需拨打这个脚本要使用比较基准日期。如果要包含参考日期,请将-lt替换为-le

编辑:一种替代解决方案,无需管道回显变量。请注意,我没有测试它,但它也应该可以工作。

#!/bin/bash 

ls -r | sed -e 's/^file_\([0-9]*\)\.csv$/\1/' | while read date; do 
    if [ $date -lt $1 ]; then 
     echo "file_${date}.csv" 
     exit 
    fi 
done 
+0

整洁! 是否可以在没有“echo $ fn”管道的情况下执行此操作(即直接将$ fn作为参数传递给sed)? – caas 2010-05-12 22:23:42

+0

由于sed对输入进行操作,因此您必须对其进行回应。你当然可以使用“这里的文件”,但这样更复杂。在读取行之前,您还可以通过sed输出ls的输出。但在这种情况下,您必须在回显它时重新创建文件名。 – petersohn 2010-05-13 07:20:08

+0

谢谢,这第二个脚本非常优雅。 Dennis Williamson建议避免分析ls并处理与模式不匹配的文件,我会稍微用一下'find'替换'ls'。 – caas 2010-05-13 11:40:30

0

排序文件名以人1如果文件名中有换行符,排序会失败。

相反,我们应该使用类似:

touch $'filename\nwith\777pesky\177chars.txt' # create a test file 

ls -1db * 

find ... -print0 | LC_ALL=C sort0 ... 

见:

查找子目录下的所有使用的扩展,

http://codesnippets.joyent.com/posts/show/2300