我在目录中找到了tar文件(备份)的列表,需要解压它们从最小到最旧的尝试,直到成功。
问题是tar文件有时会被破坏,需要解开较旧的文件。
这就是我找到最年轻的一个,但不知道如何把它放进去,然后找到下一个。
tar -xf `find /config/config_*.tar -maxdepth 1 -type f -size +1k -print0 | xargs -0 ls -hat | head -n 1`
提前致谢
答案 0 :(得分:1)
您已经有了一个工作find | xargs ls
,它为您提供了最新的文件排序列表。 (正如@sjsam指出的那样,假设你的文件名都没有包含换行符。)你可以使用bash的process-substitution功能将该列表放在一个文件中,每行一个条目,这样它就可以重新{{ 3}}。然后,只要一次备份成功,就可以退出循环。
# vvvvvvvvvvvvvvvvvvvvvv get the next filename into $tarname
while IFS= read -r tarname
do
tar -xf "$tarname" && break
# ^^^^^^^^ done with the loop if tar succeeds
done < <(find /config/config_*.tar -maxdepth 1 -type f -size +1k -print0 | xargs -0 ls -hat)
# ^ ^^^^---- the process substitution
# |
# +--------- the redirection from the process subsitution
请注意,您需要< <(...)
,而不仅仅是<(...)
。
(顺便说一下,您需要ls -hat
,还是ls -t
也会这样做?)
编辑!又名 Take 3
我受到了@ sjsam评论的启发,写了ad by a while ... read
loop,ls
替换,可以提供以NULL结尾的输出。如果您发现任何错误,请检查并提出问题!它在Cygwin上使用Perl 5.22进行了测试,但对大多数Perl 5s都适用。这是一个单独的文件 - 要安装,将ls0
放在您的路径中chmod ugo+x ls0
。
使用ls0
,上述技术可以使用aplomb处理奇怪命名的文件:
while IFS= read -r -d '' tarname
do
tar -xf "$tarname" && break
done < <(find /config/config_*.tar -maxdepth 1 -type f -size +1k -print0 | ls0 -t)
(正如@sjsam所说,-d ''
在功能上等同于-d $'\0'
)
选择2 ls0建议使用perl
代替ls
对文件名进行排序。这样你就可以处理包含换行符或其他奇怪字符的文件名。
以下是该技术的一个示例(不是OP问题的答案)。我用包含换行符的文件名测试了它。以下代码首先打印当前目录中的*.tar
个文件。此示例在每个文件名之前和之后打印斜杠,以便您可以看到具有换行符的文件名已正确处理。测试了cygwin,bash 4.3.46,perl 5.22.2。
perl -e 'opendir(my $dirh, "."); print(join "\0", sort { -M $a <=> -M $b } grep /.tar$/, readdir($dirh))' \
| while IFS= read -r -d $'\0' name
do
printf "/%s/\n" "$name"
done
所以,将这一切放在一起代码(1)回答OP的问题,(2)对于具有奇怪内容的文件名是健壮的:
perl -e 'opendir(my $dirh, "."); print(join "\0", sort { -M $a <=> -M $b } grep /.tar$/, readdir($dirh))' \
| while read -r -d $'\0' tarname
do
tar -xf "$tarname" && break
done
或者,使用流程替换,
while IFS= read -r -d $'\0' tarname
do
tar -xf "$tarname" && break
done < <(perl -e 'opendir(my $dirh, "."); print(join "\0", sort { -M $a <=> -M $b } grep /.tar$/, readdir($dirh))')
简单,对吗? ;)
来源:
-M
测试read
可以与以null结尾的字符串一起使用)答案 1 :(得分:1)
下面的脚本将
find /path/to/tarball/folder -type f -name "*.tar" -printf "%A@--%p\0" |
sort -rnz | while read -r -d '' stampedfile
do
tar -xzf "${stampedfile#*--}" >/dev/null 2>&1
[ $? -eq 0 ] && echo "Newest Working Tar: ${stampedfile#*--}" && exit
done
我们做了什么
find
列出空白终止的tarball文件,这些文件在上一次访问的时间(自纪元以来以秒为单位)和我们稍后用作分隔符的--
之前列出--
分隔符派上用场的地方time--
并尝试解压缩