aktualisieren

aktualisieren

Wie erstelle ich eine rekursive Schleife durch einen Pfad und erhalte die zuletzt erstellte tar.gzDatei in jedem Verzeichnis?

Ich möchte tar -tvf file.tar.gzdie zuletzt erstellte Datei in jedem Verzeichnis ausführen

Alle tar.gzDateien 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/bakund 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 xargsausgeführt .tar tvf

Um zwischen den einzelnen Tarballs eine Abfrage zu machen, fügen Sie -pdem xargsBefehl 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 zshwird 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-Qualifizierer
    • N: wird zu nichts erweitert, wenn es keine Übereinstimmung gibt (Nullglob)
    • /: nur Verzeichnisse
    • om: 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.gzDateien 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        

verwandte Informationen