我有一个存储备份的目录。它们的格式Complete Backup YYYY-MM-DD hh-mm-ss.tar.bz2
我发现您可以date
使用 向命令中输入日期date --date="YY-MM-DD hh:mm:ss"
。
那么我如何获得空格分隔的日期列表。日期应该通过调用来运行,date
以便它们被格式化。
我想出了这个命令,它为我提供了一个格式为 的列表(每行一个条目)YYYY-MM-DD hh-mm-ss
。那么我该如何正确地格式化它并在每一个上添加日期并用空格分隔它们呢?
dir backups/ | grep '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\\ [0-9][0-9]-[0-9][0-9]-[0-9][0-9]\.tar\.bz2$' | sed 's/\\//g' | sed 's/\.tar\.bz2//g' | sed 's/Complete Backup //g'
注意:输出将在选择循环中使用,因此属于日期的每个空格都应该被转义。
答案1
以下将重新格式化日期:
dir -1 backups | awk '/Complete\\ Backup\\ .*\.tar\.bz2/ { gsub(/\\/, ""); sub(/Complete Backup /, ""); sub(/.tar.bz2/, ""); gsub(/-/, " "); print strftime("%c", mktime($0)); }'
这是一种将其纳入选择的方法:
OIFS="$IFS"; IFS=$'\n'; set -- $(dir -1 backups | awk '/Complete\\ Backup\\ .*\.tar\.bz2/ { gsub(/\\/, ""); sub(/Complete Backup /, ""); sub(/.tar.bz2/, ""); gsub(/-/, " "); print strftime("%c", mktime($0)); }'); IFS="$OIFS"
select date in "$@"; do echo "$date"; done
这是一个对日期进行排序的版本:
OIFS="$IFS"
IFS=$'\n'
set -- $(
dir -1 backups |
awk '/Complete\\ Backup\\ .*\.tar\.bz2/ \
{
gsub(/\\/, "");
sub(/Complete Backup /, "");
sub(/.tar.bz2/, "");
gsub(/-/, " ");
VAL[NR] = mktime($0);
}
END \
{
for ( i = asort(VAL); i > 0; i-- )
{
print strftime("%a %b %d %T %Z %Y", VAL[i]);
}
}'
)
IFS="$OIFS"
select date in "$@"
do
echo "$date"
done
答案2
干得好:
dates=($(for i in backups/*.tar.bz2;do #Glob eliminates need to list all files
date=${i/Complete Backup /} #Remove "Complete Backup "
date=${date%%.*} #Remove ".tar.bz2"
date=${date/ /,} #Substitue , for space
echo $date #Echo the date for sed
done|sed -e 's/\([0-9]\+\)-\([0-9]\+\)-\([0-9]\+\)$/\1:\2:\3/'|sort -r|xargs echo))
select date in ${dates[@]};do
echo "$date"
done
还有一件事:如果您将其用于循环select
,那么当不同的日期以空格分隔时,您将如何区分它们?我的意思是您也使用空格来分隔日期和时间,因此这可能会造成混乱。
编辑
- 添加了从最新到最旧的日期排序,因为您的评论表明您需要以这种方式排序。
- 添加了用逗号分隔日期和时间的代码,以便
select
可以从新条目中区分日期和时间对。 将整个数据包装在一个中将日期存储到一个数组中,然后通过循环对其进行迭代,select
循环select
以避免每次重新运行循环时都必须重新解析日期。