![更新](https://linux22.com/image/110503/%E6%9B%B4%E6%96%B0.png)
如何通过路径进行递归循环并获取tar.gz
每个目录中最新创建的文件?
我想tar -tvf file.tar.gz
在每个目录中最新创建的文件上运行
所有tar.gz
文件都位于第二级目录中。因此循环的最大深度为2
该脚本只会打印每个目录
cd $base_dir
find . -type d -printf '%f\n'
基本目录是/var/www/bak
,所有 tar.gz 文件的位置如下
/var/www/bak/site1/www/file.tar.gz
/var/www/bak/site1/db/file.tar.gz
/var/www/bak/site2/www/file.tar.gz
/var/www/bak/site2/db/file.tar.gz
更新
find_tarballs (){
cd $base_dir
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD}/\"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1
}
filesize (){
ls -lh $1 | awk -F " " {'print $5'}
}
output="$(find_tarballs)"
set -- $output
shift
for tarball; do
echo "$tarball"
if [ ${tarball##*.} = 'gz' ]; then
list="$(tar -tzf $tarball)"
echo "Filesize: $(filesize $tarball), Files: $(echo "$list" | wc -l)\n"
echo 'Press ENTER to list files...'
read key
echo "$list"
else
echo "Filesize: $(filesize $tarball)"
fi
echo ''
done
答案1
假设您的路径不包含空格或换行符:
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1
将找到所有 tarball,在每个包含的目录中运行给定的 shell 片段,并过滤结果,以便为每个目录仅保留一个结果。
要查看 tarball 的内容,假设它们的文件名也不包含空格或换行符:
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1 | tr ' ' / | xargs -n 1 tar tvf
将用“/”替换路径与文件名之间的空格,并将结果传递给xargs
将tar tvf
在每个文件上运行的程序。
要在每个 tarball 之间进行提示,请添加-p
到xargs
命令中:
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1 | tr ' ' / | xargs -p -n 1 tar tvf
答案2
使用zsh
,以典型的只写方式:
for dir (*/*(N/)) (){(($#)) && tar tvf $1} $dir/*.tar.gz(Nom[1])
for var (values) cmd
: 的缩写形式for var in values; do cmd; done
(N/)
,(Nom[1])
: 全局限定符N
:如果没有匹配项,则扩展为空(nullglob)/
:仅目录om
:按修改时间排序(最新的在前)[1]
:仅限第一个匹配项
(){...} args
: 带有参数的匿名函数。
使用 GNU 工具(仍然不假设文件名可能包含哪些字节,但遍历隐藏目录并包括隐藏tar.gz
文件)和任何类似 Bourne 的 shell,等价的可能是:
LC_ALL=C find . -mindepth 3 -maxdepth 3 -name '*.tar.gz' -printf '%T@:%p\0' |
sort -zn | LC_ALL=C awk -v RS='\0' -v ORS='\0' '
{match($0, ":((.*)/.*)", parts); newest[parts[2]] = parts[1]}
END {for (dir in newest) print newest[dir]}' |
xargs -r0n1 tar tvf