
Wie erstelle ich eine rekursive Schleife durch einen Pfad und erhalte die zuletzt erstellte tar.gz
Datei in jedem Verzeichnis?
Ich möchte tar -tvf file.tar.gz
die zuletzt erstellte Datei in jedem Verzeichnis ausführen
Alle tar.gz
Dateien befinden sich in der zweiten Verzeichnisebene. Die maximale Tiefe der Schleife beträgt also 2
Dieses Skript druckt nur jedes Verzeichnis
cd $base_dir
find . -type d -printf '%f\n'
Das Basisverzeichnis ist /var/www/bak
und alle tar.gz-Dateien befinden sich wie folgt
/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
aktualisieren
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
Antwort1
Vorausgesetzt, Ihre Pfade enthalten keine Leerzeichen oder Zeilenumbrüche:
find . -name \*.tar.\* -execdir sh -c "echo -n \"\${PWD} \"; ls -t *.tar.* | head -n 1" \; | sort -u -k1,1
findet alle Tarballs, führt den angegebenen Shell-Ausschnitt in jedem enthaltenen Verzeichnis aus und filtert das Ergebnis, sodass für jedes Verzeichnis nur ein Ergebnis übrig bleibt.
So zeigen Sie den Inhalt der Tarballs an (vorausgesetzt, ihre Dateinamen enthalten keine Leerzeichen oder Zeilenumbrüche):
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
ersetzt das Leerzeichen, das den Pfad vom Dateinamen trennt, durch „/“ und übergibt das Ergebnis an which wird für jede Datei xargs
ausgeführt .tar tvf
Um zwischen den einzelnen Tarballs eine Abfrage zu machen, fügen Sie -p
dem xargs
Befehl Folgendes hinzu:
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
Antwort2
Mit zsh
wird im typischen Nur-Schreib-Modus Folgendes ausgeführt:
for dir (*/*(N/)) (){(($#)) && tar tvf $1} $dir/*.tar.gz(Nom[1])
for var (values) cmd
: kürzere Form vonfor var in values; do cmd; done
(N/)
,(Nom[1])
: Glob-QualifiziererN
: wird zu nichts erweitert, wenn es keine Übereinstimmung gibt (Nullglob)/
: nur Verzeichnisseom
: Sortierung nach Änderungszeitpunkt (neueste zuerst)[1]
: nur das erste Spiel
(){...} args
: anonyme Funktionen mit ihren Argumenten.
Mit GNU-Tools (die immer noch keine Annahmen über den möglichen Byte-Gehalt von Dateinamen treffen, sondern versteckte Verzeichnisse durchsuchen und versteckte tar.gz
Dateien einschließen) und jeder Bourne-ähnlichen Shell könnte das Äquivalent folgendermaßen aussehen:
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