Aus mit tree erstellter Datei nur den Dateinamen (mit Endung) und die Dateigröße extrahieren

  • Hallo,

    ich möchte aus einer mit tree erstellten Datei nur die Dateinamen (mit Endung) und die Dateigröße extrahieren.

    Also in der Form:

    musik.mp3 [395436]

    Achtung, der Dateiname und auch die Verzeichnisnsmen können Leerzeichen enthalten.

    Danke Ziggi

  • Aus mit tree erstellter Datei nur den Dateinamen (mit Endung) und die Dateigröße extrahieren? Schau mal ob du hier fündig wirst!

  • Bei mir kommt bei einer mit tree erstellten Ausgabe keine Dateigrösse.

    Nur eine feste Anzahl von Zeichen bis zum Beginn des Dateinamens, der mit einem (nichtsichtbaren) "\n" (aka newline) abgeschlossen ist.


    Servus !

    RTFM = Read The Factory Manual, oder so

    Edited once, last by RTFM (March 22, 2024 at 7:08 PM).

  • Ist sicherlich besser zu machen, aber als Schnellschuß sollte es reichen:

    Edit:

    folgende Zeile macht Probleme:

    mySize=$(du -s$param_du "$i" | tr '\t' '@' | cut -d'@' -f1)

    und habe sie deswegen ausgetauscht.

    Edited once, last by Bergwichtel: kleine Fehlerkorrektur (March 22, 2024 at 8:17 PM).

  • Ist sicherlich besser zu machen, aber als Schnellschuß sollte es reichen:

    Geht noch nicht mit Leerzeichen in Dateinamen:

    :rolleyes: sudo !!

  • du würde man hier auch eher nicht verwenden, denn das liefert eine andere Zahl als tree -s. stat würde man hier eher nehmen.

    Die Frage ist aber auch ob das überhaupt möglich ist, denn die Ausgangsfrage war ja wie man diese Infos aus einer Datei bekommt die mit tree erstellt wurde, was ja auch bedeuten kann es gibt nur diese Datei und keinen Zugriff auf das Dateisystem aus dem die erstellt wurde.

    “It is easier to optimize correct code than to correct optimized code.” — Bill Harlan

  • Die Frage ist aber auch ob das überhaupt möglich ist, denn die Ausgangsfrage war ja wie man diese Infos aus einer Datei bekommt die mit tree erstellt wurde, was ja auch bedeuten kann es gibt nur diese Datei und keinen Zugriff auf das Dateisystem aus dem die erstellt wurde.

    Das ganze führende Geraffel kriege ich mit sed weg. Ausgabe mit awk müsste hinzubekommen sein, wobei ich da die Leerzeichen in Dateinamen auch noch nicht drinhabe.

    tree setzt ja mindestens ── voran, mit dem man das Zeilenweise arbeiten könnte.

    Ich bin von tree -s in Datei umgeleitet ausgegangen bzw. habe gleich tree -s -L 1 an sed gepiped. Wäre aber gut zu wissen wie die Datei erstellt wurde, ja.

    :rolleyes: sudo !!

  • Oh, Mißverständnis.

    Ich glaubte, das der OP versteht, daß das tree garnicht benötigt wird. tree macht es nur umständlicher.

    Code
    $ cd ~/Dateien/ab/hier/ausgeben
    /home/USER/Dateien/ab/hier/ausgeben $ ./das_gepostete_Skript.bash

    Danach wird ab dem aktuellen Verzeichnis der

    Dateiname [größe]

    ausgegeben.

    Natürlich muß das Ganze noch an seinen Wünschen angepaßt werden. Z.B. kann man einen Verzeichnisnamen übergeben, von wo aus alle Dateien ausgegeben werden. Bzw. die Suchtiefe, die Dateiart, etc.


    __blackjack__

    ~> stat screenshot_screens.jpg | head -n2
    Datei: screenshot_screens.jpg
    Größe: 44881 Blöcke: 88 EA Block: 4096 reguläre Date

    ~> du -b screenshot_screens.jpg
    44881 screenshot_screens.jpg

    Meiner Meinung nach ist tree für die Aufgabe das falsche Mittel.

  • Falls die tree-Ausgabe in einer Datei umgeleitet wurde und man diese parsen will, habe ich einen Ansatz, der aber noch einen Fehler enthält. Ich sehe ihn momentan einfach nicht. Vielleicht weiß es jemand anderes.

    Hier der Ansatz:

    und dann:

    Um die letzte Zeile wegzubekommen, kann man folgendes tun:

    cat ./treeausgabe.txt | head -n-1 | sed -e 's/[├│└─]*//g' -re 's/^[ \t]+//'

    Ich hoffe, daß dies schon etwas weiter hilft.


    Edit: Habe noch ein bischen probiert, aber ich bekomme das " " nur per C&P hin (siehe Bildanhang).
    Das sieht dann so aus:

    Für den Rest habe ich jetzt keinen Nerv mehr.

    Was für Zeichen ist das? Es raubt mir Schlaf und Nerv. ;)

    Edit 2:
    Habe herausgefunden, was für Zeichen das ist (https://en.wikipedia.org/wiki/Non-breaking_space), bin aber zu doof das (in einer RegEx) einzugeben. Das Zeichen reinzukopieren funktioniert zwar, aber es soll ja lesbar sein (\x{00A0} klappt bei mir nicht).

  • Mein Versuch war es das ohne Regex, bzw. pattern zu schaffen und das kam dabei raus:

    Bash
    #! /bin/bash
    
    while read line 
        do 
            if [[ $line =~ ".mp3" ]] then set $line 
                IFS=']' read -ra line_array <<< ${*:4} ; echo ${line_array[1]} ${line_array[0]}        
            fi
    done < /home/hyle/skripte/tree_ausgabe.txt


    Hier der entsprechende Auszug aus der tree_ausgabe.txt, Unschwer zu erkennen handelt es sich dabei um ein Album von Ministry. 🤘


    Das Ergebnis ist folgendes:


    //Edit

    Wer die eckigen Klammern um die Dateigröße will, kann die einfach dazu schreiben.

  • Eine Lösung ohne reguläre Ausdrücke in QBasic (lässt sich unter Linux mit FreeBASIC compilieren):

    “It is easier to optimize correct code than to correct optimized code.” — Bill Harlan

  • hyle Die ”Linien” sind ja alle *vor* den eckigen Klammern. INSTR() such die Position einer Zeichenkette in einer anderen, und MID$() schneidet aus einer Zeichenkette ab einer Position eine angegebene Länge aus oder alles ab der Position falls keine Länge angegeben ist.

    Könnte sein, dass das auch mit Visual Basic funktioniert, das habe ich aber nur ausgewählt, weil es kein QBasic gibt in der Liste. Geschrieben und ausprobiert hatte ich das unter DOS. Und dann noch mal kurz unter Linux mit FreeBASIC getestet.

    Ja das verarbeitet alle Zeilen, ich hatte das Beispiel mit mp3 nur als Beispiel verstanden und nicht das alle Dateien MP3s sein müssen. Wirklich *zuverlässig* ermitteln was Datei und was Verzeichnis ist, kann man ja nicht.

    “It is easier to optimize correct code than to correct optimized code.” — Bill Harlan

  • Wirklich *zuverlässig* ermitteln was Datei und was Verzeichnis ist, kann man ja nicht.

    Könnte man schon über die Dateigröße (4096) der Verzeichnisse, aber das wäre dann wirklich zu viel des Guten. ^^

    Die ”Linien” sind ja alle *vor* den eckigen Klammern. INSTR() such die Position einer Zeichenkette in einer anderen, und MID$() schneidet aus einer Zeichenkette ab einer Position eine angegebene Länge aus oder alles ab der Position falls keine Länge angegeben ist.

    Ah, verstehe! Sucht das nur nach dem ersten Zeichen einer Zeichenkette oder nach allen Zeichen? Meine Frage ist wegen meiner tree_ausgabe.txt-Datei Zeile #6:

    Code
    │                   └── [       4096]  Houses Of The Mole [MYNCD023]

    Was würde da passieren?

  • Diese Problemstellung ist fuer mich mal wieder ein Beispiel dafuer dass es verschiedenene Wege nach Rom gibt - also man ein Problem loesen kann. Aber es zeigt mir auch dass es immer sinnvoll ist einen vorgeschlagenen Loesungsweg zu hinterfragen welches der Loesungsvorschlag von Tell in #10 beweist :)

  • Mit Python würde ich das vermutlich über find() und split() erledigen.

    //Edit

    framp Oft muss man (leider) mit den gegebenen Umständen arbeiten, z.B. wenn ein Kollege etwas erledigt hat und nun nicht mehr da ist. In dem Fall hätte der Kollege diese Textdateien erstellt, weil er zu umständlich gedacht hatte und als Nachfolger müsste man sich mit dem vorhandenen Quark auseinandersetzen. Das ist trotzdem ein interessantes Thema, vor allem was die verschiedenen Lösungswege betrifft.

    //Edit2

    Wenn ich so darüber nachdenke, wäre set Beitrag #13 gar nicht nötig. Das könnte man auch per IFS lösen. :daumendreh2:

    Bash
    #! /bin/bash
    
    while read line 
        do 
            if [[ $line =~ ".mp3" ]] then IFS='[' read -ra line_array <<< $line
                IFS=']' read -ra a <<< ${line_array[1]} ; echo ${a[1]} ${a[0]}        
            fi
    done < /home/hyle/skripte/tree_ausgabe.txt
  • Anbei noch ein Oneliner von mir mit sed und head

    Code
    sed -E 's/.*\[\s*(.*)\]+(.*)/\2 \1/; s/^\s+//g; s/^[0-9]+.*//g' <<< "$(tree -s <directory>)" | head -n -2

    hyle Ich sehe Deinen Punkt. Im konkreten Fall ist der TE aber von tree angekommen und hat somit nicht das Altlastproblem.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!