
如何透過路徑進行遞歸循環並獲取tar.gz
每個目錄中最新建立的檔案?
我想tar -tvf file.tar.gz
在每個目錄中最新建立的文件上運行
所有tar.gz
檔案都位於第二級目錄。
該腳本只會列印每個目錄
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