アップデート

アップデート

パスを再帰ループして、tar.gz各ディレクトリで最後に作成されたファイルを取得するにはどうすればよいですか?

tar -tvf file.tar.gz各ディレクトリ内の最後に作成されたファイルに対して実行したい

すべてのtar.gzファイルは2番目のディレクトリレベルにあります。したがって、ループの最大深度は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 を検索し、各ディレクトリで指定されたシェル スニペットを実行し、各ディレクトリに対して 1 つの結果のみが保持されるように結果をフィルターします。

ファイル名にもスペースや改行が含まれていないと仮定して、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 のようなシェルを使用すると、同等のものは次のようになります。

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        

関連情報