更新

更新

如何透過路徑進行遞歸循環並獲取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

將用“/”替換路徑與檔案名稱之間的空格,並將結果傳遞給xargstar tvf在每個檔案上執行的程式。

要在每個 tarball 之間進行提示,請添加-pxargs命令中:

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        

相關內容