Zum umsortieren nehme ich awk -F'#' '{print $3$2$1}' funktioniert leider nur statisch. Wie bringe ich awk dazu die Spalten anhand eines Musters zu sortieren? Oder ist ein anderes Werkzeug besser geeignet?

Die Ausgabe die ich sortieren möchte sieht in etwas so aus

Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt
Muster3: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster1: X-Beliebiger Inhalt
Muster2: X-Beliebiger Inhalt# Muster1: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt

und soll so aussehen

Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt
Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt
Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt

Probier mal:
awk -F'#' '{print $3, $2, $1} | sort

Mit sed Muster umbenennen und mit sort sortieren umschifft das Problem, dann kann ich auch auf awk verzichten.

Wenn ich das richtig verstehe ist awk nicht in der Lage Text zu analysieren und erkennt nur Spalten anhand ihrer Position, Richtig?

sort kann man auch einen Separator (in diesem Fall #) übergeben, der die Felder unabhängig von der Position abgrenzt, und die Sortierung wird dann über Keys durchgeführt, für drei Felder also
sort -t# -k1,1 -k2,2 -k3,3

Ich muss gestehen, dass ich nicht weiß, was du konkret möchtest.

Welche Befehlsausgabe soll für was in welche Form gebracht werden?

  • Andy@Arch hat auf diesen Beitrag geantwortet.

    Alternativ nimm eine andere Sprache.

    $ cat org.txt 
    Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt
    Muster3: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster1: X-Beliebiger Inhalt
    Muster2: X-Beliebiger Inhalt# Muster1: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt

    In Ruby wäre es ein Einzeiler:

    $ ruby -a -F'# ' -ne 'puts $F.sort.join("# ").tr("\n","")' org.txt

    ergibt:

    Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt
    Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt
    Muster1: X-Beliebiger Inhalt# Muster2: X-Beliebiger Inhalt# Muster3: X-Beliebiger Inhalt

    Das "Magische" dabei ist:

    • -ne sorgt hier für das zeilenweise einlesen aus org.txt
    • -F'# ' trennt die jeweilige Zeile bei <RauteLeerstelle> und übergibt
    • -a diese Fundstellen an die Variable $F als Array

    Im Code wird das Array dann sortiert und mittels join wieder in einen String umgewandelt der diese Trennzeichen("# ") wieder enthält. Mittels tr werden in diesem String noch enthaltene Newlines entfernt.

    Die "Crux" an der Aufgabe ist halt, das Sortieren jeweils für jede Zeile zu erledigen, damit also jede Zeile nach der Sortierung "Muster1", "Muster2", "Muster3" erfolgt.

    pacman -S ruby
    ftw

    Hier ein wenig eleganter Ansatz:

    {
        muster[1]=""
        muster[2]=""
        muster[3]=""
    
        for(i=1;i<=NF;i++) {
            if($i ~ /^Muster1:/) {
                muster[1]=$i
            }
            else if($i ~ /^Muster2:/) {
                muster[2]=$i
            } 
            else if($i ~ /^Muster3:/) {
                muster[3]=$i
            }
        }
        print muster[1] FS muster[2] FS muster[3]
    }

    Es wird dabei nicht geprüft, ob die Anzahl Felder stimmt und ob jedes Muster dann auch nur einmal vorhanden ist. Bei ungültiger Eingabe werden Inhalte dann einfach stillschweigend verworfen.

    Das muss besser gehen aber ich fasse awk auch nur alle Jubeljahre mal an.

    tuxnix Welche Befehlsausgabe soll für was in welche Form gebracht werden?

    Ursprünglich ging es mir darum Teile der Ausgabe von ffprobe in Spalten in eine *.csv umzuleiten, so das ich das in eine calc Tabelle einfügen kann. Das habe ich aber mittlerweile ohne awk geschafft, mit sed und sort.
    Konkret sieht das momentan so aus
    ffprobe "$mp3source" 2>&1 | grep -E ' album | artist | title | publisher | copyright | TSRC ' |tr -s ' ' |sed -e 's#album #A#g' -e 's#artist #B#g' -e 's#title #C#g' -E -e 's#copyright |publisher #D#g' -e 's#TSRC #E#g' |sort |tr '\n' '\t'
    Funktionieren tut es, wäre halt schön wenn man den Schritt mit sed überspringen könnte und das nach eigenen Filterregeln sortieren könnte.

      pacman -Si mp3info

      https://man.archlinux.org/man/mp3info.1
      Siehe die Ausgabeoptionen mittels Parameter -p

      Damit solltest du jede Info in jedes "Format" ablegen können.

      Trotzdem ist mir jetzt auch nicht klar, was du genau machst und was du genau erwarten würdest. Mit deiner ursprünglichen Aufgabenstellung hat das IMHO nichts mit zu tun.

      Andy@Arch Konkret sieht das momentan so aus

      Wo ist die Verbindung zu einer CSV-Datei?
      Wenn ich das auf irgendwas bei mir loslasse kommt:
      B: Nancy Sinatra C: Bang, Bang
      raus? Wo ist da CSV? Was fängst du damit an?

      Zeige doch am besten mal an einem realen Beispiel bei dir:
      a) Was dein Code damit macht
      b) Wie deine Ausgabedatei damit aussieht
      c) Wie du es gerne hättest

      Hint: Schau dir mal die manpage zu ffprobe an, dort gibt es einige Optionen die für dein Vorhaben interessant sein könnten. Oder auch:
      https://wiki.ubuntuusers.de/ffprobe/
      Gerade die diversen Möglichkeiten des -print_format Parameters könnten dich weiterführen.
      Bsp:

      $ ffprobe -v quiet -show_format -print_format flat /mnt/s01/Media/musik/Sammlung/Black\ Sabbath/Black\ Sabbath\ -\ Paranoid.mp3 
      format.filename="/mnt/s01/Media/musik/Sammlung/Black Sabbath/Black Sabbath - Paranoid.mp3"
      format.nb_streams=1
      format.nb_programs=0
      format.format_name="mp3"
      format.format_long_name="MP2/3 (MPEG audio layer 2/3)"
      format.start_time="0.000000"
      format.duration="168.785125"
      format.size="2701312"
      format.bit_rate="128035"
      format.probe_score=51
      format.tags.title="Paranoid"
      format.tags.artist="Black Sabbath"
      $ ffprobe -v quiet -show_format -print_format compact /mnt/s01/Media/musik/Sammlung/Black\ Sabbath/Black\ Sabbath\ -\ Paranoid.mp3 
      format|filename=/mnt/s01/Media/musik/Sammlung/Black Sabbath/Black Sabbath - Paranoid.mp3|nb_streams=1|nb_programs=0|format_name=mp3|format_long_name=MP2/3 (MPEG audio layer 2/3)|start_time=0.000000|duration=168.785125|size=2701312|bit_rate=128035|probe_score=51|tag:title=Paranoid|tag:artist=Black Sabbath
      ffprobe -v quiet -show_format -print_format csv /mnt/s01/Media/musik/Sammlung/Black\ Sabbath/Black\ Sabbath\ -\ Paranoid.mp3 
      format,/mnt/s01/Media/musik/Sammlung/Black Sabbath/Black Sabbath - Paranoid.mp3,1,0,mp3,MP2/3 (MPEG audio layer 2/3),0.000000,168.785125,2701312,128035,51,Paranoid,Black Sabbath

      //Edit: Ich glaube, langsam verstehe ich um was es dir bei dem ganzen Sortierdingens geht:
      Du bist mit der Reihenfolge in der ffprobe die Meta-Tags ausgibt nicht zufrieden und möchtest das eigenem Belieben in "Spalten" anordnen.
      Kurz: Wenn es sich nur um mp3 handelt nimm mp3info:
      mp3info -p "%l,%a,%t\n" /mnt/s01/Media/musik/Sammlung/Black\ Sabbath/Black\ Sabbath\ -\ Paranoid.mp3
      Du hast volle Kontrolle über die Reihenfolge und das Format/Trenner

      @Martin-MS hat dir ja noch eine andere Alternative aufgezeigt.

      Wenn es unbedingt ffprobe sein soll:
      Du kannst zwar für die Ausgabe (ohne grep'pen) die gewünschten Tags angeben z.B. mittels
      -show_entries format_tags=artist,title
      aber die Ausgabe-Reihenfolge ist damit nicht wählbar. Da wäre ein Ansatz der, den auch @Martin-MS in einem obigen Post mit sort zeigte (Sortieren nach Keys) eine Möglichkeit.
      Ich halte ffprobe aber nicht für das beste Werkzeug für Metadaten, da es z.B. diese für .ogg oder .mp3 in ganz unterschiedlichen Formatstreams sucht/bezeichnet/anzeigt. Das ist IMHO nicht filterbar wenn es um unterschiedliche Medienformate geht.

      mediainfo (aus dem gleichnamigen Paket) ist da IMHO universeller und kann die Tags auch nach gewünschter Reihenfolge ausgeben. z.B:

      $ mediainfo --Output="General;%Album%|%Performer%|%Title%" /mnt/s01/Media/musik/Sammlung/Muddy\ Waters/Collection\ -\ 25\ Songs\ \(1993\)/09\ -\ Muddy\ Waters\ -\ 40\ Days\ And\ 40\ Nights.ogg 
      Collection - 25 Songs|Muddy Waters|40 Days And 40 Nights

      Welche Tags du verwenden kannst zeigt dir:
      $ mediainfo --Info-Parameters
      Die gebräuchlichsten findest du in der Liste oben unter General.
      Mit mediainfo wären halt sehr viele unterschiedliche Medienformate abdeckbar.

      • Andy@Arch hat auf diesen Beitrag geantwortet.

        Andy@Arch Ursprünglich ging es mir darum Teile der Ausgabe von ffprobe in Spalten in eine *.csv umzuleiten, so das ich das in eine calc Tabelle einfügen kann.

        Dann versuche es mal mit
        exiftool -csv -TAG -genre -TAG -album -TAG -artist -TAG -title -TAG -publisher -TAG -copyright "$mp3source"

        Das schreibt die ausgewählten tags direkt in ein csv

        GerBra Kurz: Wenn es sich nur um mp3 handelt nimm mp3info:

        .......does not have an ID3 1.x tag. ist halt doof wenn die mp3 ID3v2 Tag hat

        GerBra Wenn es unbedingt ffprobe sein soll:

        hat halt den Vorteil das es meistens schon vorhanden ist, aber mediainfo schau ich mir mal genauer an

        • GerBra hat auf diesen Beitrag geantwortet.

          mp3info

          Andy@Arch .......does not have an ID3 1.x tag. ist halt doof wenn die mp3 ID3v2 Tag hat

          Stimmt, ist mir nie als Fehler aufgefallen da ich immer beide Versionen drin habe. Ist aber auch in der manpage unter Bugs vermerkt. Schade.

          mediainfo kommt aber damit klar.

          Anmerkung: Im Thread hätte man sich IMHO einiges an "Arbeit" ersparen können, wenn du von Anfang an diese Infos bzgl. ffprobe, bzw. um was es dir konkret im Eingangspost geht, aufgezeigt hättest. Selbst die sehr "allgemeine" Frage nach "Sortierung von Spalten" wären dann in einem ganz anderen Zusammenhang zuordenbar gewesen.
          Ich bin eingangs wirklich davon ausgegangen du hättest exakt eine "Textdatei" wie in Post #1 gezeigt und hättest diese gerne in das ebenfalls dort gezeigte Format gewandelt.

          • Andy@Arch hat auf diesen Beitrag geantwortet.

            GerBra Anmerkung: Im Thread hätte man sich IMHO einiges an "Arbeit" ersparen...................

            Anmerkung: Der Thread hat sich auch in eine komplett andere Richtung entwickelt wie ich anfangs dachte. 🙂

            Als kleines I-Tüpfelchen versuche ich zum Schluss nochmal den File zu sortieren, zuerst nach Spalte 1 (Tracknummer) und danach nach Spalte 2 (Album). sort -t $'\t' -hk 1,1 -k 2,2 "$sourcepath/Mp3Info.csv" -o "$sourcepath/Mp3Info.csv" aber warum auch immer greift die zweite Sortierung nicht. Was mach ich falsch?

            • Martin-MS hat auf diesen Beitrag geantwortet.

              Andy@Arch aber warum auch immer greift die zweite Sortierung nicht. Was mach ich falsch?

              Das kann man ohne die Eingabedaten gesehen zu haben schlecht sagen. Du kannst den sort noch mit der --debug-Option starten, dann siehst du, ob der Delimiter richtig erkannt wurde und auf welche Länge sich der Key für die Sortierung erstreckt.

              5 Tage später

              Nur fürs Protokoll, so funktioniert es

              sort -t $'\t' -k 2,2 -k 1,1h