
パスを再帰ループして、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