我有一个包含自动创建的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;
答案 0 :(得分:18)
ls -1 | tail -n 1
如果要将其分配给变量,请使用$(...)
或反引号。
FILE=`ls -1 | tail -n 1`
FILE=$(ls -1 | tail -n 1)
答案 1 :(得分:7)
@ Sjoerd的回答是正确的,我只会从中挑选一些尼特:
如果您将输出传输到某处,则不需要-1
选项来强制每行一个路径:
ls | tail -n 1
您可以使用-r
以相反的顺序获取商家信息,然后选择第一个:
ls -r | head -n 1
gunzip some.log.gz
会将未压缩的数据写入some.log
并删除some.log.gz
,这可能是也可能不是您想要的(可能不是)。如果要保留压缩源,请将其输入gunzip
:
gunzip < some.file.gz
您可能希望保护脚本免受dir不包含文件的情况,因为
gunzip $empty_variable
扩展为
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