Shell脚本:按字母顺序获取文件夹中最后一个文件的名称

时间:2010-07-02 07:48:30

标签: shell

我有一个包含自动创建的MySQL数据库备份的文件夹。它们的名称由备份的日期组成,如下所示:

2010-06-12_19-45-05.mysql.gz  
2010-06-14_19-45-05.mysql.gz  
2010-06-18_19-45-05.mysql.gz  
2010-07-01_19-45-05.mysql.gz

有什么方法可以获取列表中最后一个文件的文件名,即按字母顺序排列的文件名?

在shell脚本中,我想做类似

的事情
LAST_BACKUP_FILE= ???
gunzip $LAST_BACKUP_FILE;

4 个答案:

答案 0 :(得分:18)

ls -1 | tail -n 1

如果要将其分配给变量,请使用$(...)或反引号。

FILE=`ls -1 | tail -n 1`
FILE=$(ls -1 | tail -n 1)

答案 1 :(得分:7)

@ Sjoerd的回答是正确的,我只会从中挑选一些尼特:

  1. 如果您将输出传输到某处,则不需要-1选项来强制每行一个路径:

    ls | tail -n 1
    
  2. 您可以使用-r以相反的顺序获取商家信息,然后选择第一个:

    ls -r | head -n 1
    
  3. gunzip some.log.gz会将未压缩的数据写入some.log并删除some.log.gz,这可能是也可能不是您想要的(可能不是)。如果要保留压缩源,请将其输入gunzip

    gunzip < some.file.gz
    
  4. 您可能希望保护脚本免受dir不包含文件的情况,因为

    gunzip $empty_variable
    
  5. 扩展为

        gunzip
    

    并且此类调用将无限期地等待标准输入的数据:

        latest="$(ls -r /some/where/*.gz | head -1)"
        if test -z "$latest"; then
          # there's no logs yet, bail out
          exit
        fi
        gunzip < $latest
    

答案 2 :(得分:4)

如果文件名有异常字符,

ls在被其他命令解析时会产生意外结果。以下内容始终有效:

for LAST_BACKUP_FILE in *; do : ; done

for LAST_BACKUP_FILE in *循环遍历当前目录中的每个文件名,将每个文件存储在$LAST_BACKUP_FILE

do :什么都不做

done在最后一个文件

之后完成

现在,最后一个文件存储在$LAST_BACKUP_FILE

如果您碰巧想要第一个文件,请使用:

for FIRST_BACKUP_FILE in *; do break; done

第一个文件存储在break后,$FIRST_BACKUPT_FILE语句跳出循环。

答案 3 :(得分:2)

shell比许多人想象的更强大。让它适合你。假设文件名没有空格,

set -- $(ls -r *.gz)
LAST_BACKUP_FILE=$1

使用单个fork,没有管道来完成这个技巧,如果你的shell支持算术扩展,你甚至可以避免使用fork,如

set -- *.gz
shift $(($# - 1))
LAST_BACKUP_FILE=$1