Bash: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen



  • Hallo, ich suche nach einem einfachen Weg, wie ich hier das cut weglassen kann, und dennoch eine "vernünftige" Tabelle darstellen lassen kann:

    find . -mindepth 1 -maxdepth 1 -type d | cut -c3-10 | tr -s ' ' '_' | xargs -n5

    Das cut (beginnt übrigens bei Index 1...) schneidet die ersten zwei Zeichen ab ("./") und begrenzt zudem die Länge auf 7.

    Ich möchte aber eher volle Ordnernamen, aber dann geht die Tabelle nicht mehr, ebenso bei Leerzeichen.

    Außerdem möchte ich noch die Zeilen und Spalten "kippen"... Das heißt:

    a b c d e
    f g h i j
    k
    

    soll zu

    a f k
    b g
    c h
    d i
    e j
    

    werden.



  • ls -d */ macht bei mir automatisch Columns (wenn du eh nur 1 level haben willst, warum dann find?) - aber natürlich mit / am Ende und ohne Leerzeichen zu replacen. Ansonsten ls -C.

    Ansonsten: man column
    find ... | column -x



  • @wob sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    Ansonsten: man column

    column bringt nichts, weil es einfach nur die Konsole voll klatscht. Bitte auch die Überschrift genau lesen, bevor du rtfm schreibst. Ich will genau 5 Spalten haben.



  • @ShredderButtonOn zu deinem Zeilen kippen, mit Bash, kannst du meiner Meinung nach das mit dem awk Kommando irgendwie zusammenschustern. Mit reinem Bash selbst, ich weiß nicht.

    Außerdem habe ich dein Kommando, (zumindest ein Teil davon) ausgeführt und verstehe nicht was du damit bewilligen willst? Außer Schaden anzurichten.



  • @siri sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    Außerdem habe ich dein Kommando, (zumindest ein Teil davon) ausgeführt und verstehe nicht was du damit bewilligen willst?

    Wir haben im Büro einen Ordner mit Kunden, die zu bearbeiten sind. Es sind viele Kunden, und wir sind nur 5 Leute. Jeder soll gleich viele Kunden übernehmen. Ergo, die Aufteilung (oder Gruppierung).



  • @ShredderButtonOn DAS ist dann wohl dein Problem.



  • DU hast nach dem Use Case gefragt. 😃

    Na ja, aber es funktioniert ja ... Nur halt abgehackt.



  • @ShredderButtonOn mich stört der Dialog nicht, ich sagte nur, dass du mit deinem One-Liner einfach nur ein bisschen Chaos anrichtest und man nicht nachvollziehen kann was du eigentlich tun willst.


  • Mod

    Auch wenn das sicher eine interessante Herausforderung für die Kommandozeilenmittel wäre, besonders als Einzeiler, ist komplexe Zeichenkettenmanipulation wohl ein Fall, wo man besser eine höhere Scriptsprache wählen sollte. Besonders das Transponieren wird sonst ekelig. In Python oder ähnlichen Sprachen wären das bloß wenige, kurze, einfach verständliche Zeilen.

    Man kann das ja sogar einfach kombinieren und die Handhabe der Ordnernamen mit den Kommandozeilen machen (Denn dafür sind die ideal!) und diese dann an das Script zur Ausgabe übergeben.



  • @SeppJ tut mir Leid aber ich verstehe nicht was du meinst.

    Die Zeile ist eigentlich ein totaler Bullshit und das sollte man so nicht machen,



  • @siri sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    Die Zeile ist eigentlich ein totaler Bullshit

    Eh, nein?



  • @ShredderButtonOn sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    @siri sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    Die Zeile ist eigentlich ein totaler Bullshit

    Eh, nein?

    Das xargs an deinem Ende, ist das, was mich irritiert.



  • @siri sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    @ShredderButtonOn sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    @siri sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    Die Zeile ist eigentlich ein totaler Bullshit

    Eh, nein?

    Das xargs an deinem Ende, ist das, was mich irritiert.

    Dafür könnte man auch column verwenden ... aber das funktioniert wie gesagt nicht ganz


  • Mod

    @siri sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    @SeppJ tut mir Leid aber ich verstehe nicht was du meinst.

    Du kannst 150 Minuten daran feilen, das optimal mit den GNU Core Utilities als Einzeiler zu basteln, bis das zuverlässig und mit allen erdenklichen Sonderfällen funktioniert. Und das Ergebnis würde den wenigen Leuten, die das lesen können, die Tränen kommen lassen vor lauter Schönheit, dass jemand so etwas geschaffen hat.

    Oder du kannst das in 15 Minuten in einer "richtigen" Programmiersprache deiner Wahl machen, und es würde nicht einmal einen Eintrag als Übungsaufgabe in einem Lehrbuch wert sein, weil zu einfach.

    Optimalerweise aber eine Kombination aus beidem, denn find . -mindepth 1 -maxdepth 1 -type d will man dann doch nicht neu erfinden, in egal welcher Sprache.



  • @SeppJ das sind wahrhaft weise und werte Worte die du für deinen Beitrag gewählt hast

    @SeppJ sagte in BASH: Tabelle mit 5 Spalten aus Ordnernamen in einem Ordner erstellen:

    Oder du kannst das in 15 Minuten in einer "richtigen" Programmiersprache deiner Wahl machen, und es würde nicht einmal einen Eintrag als Übungsaufgabe in einem Lehrbuch wert sein, weil zu einfach.

    Dem stimme ich nicht zu. Ja, Bash ist komplett die falsche Sprache um solche Sachen zu bewerkstelligen und andere Sprachen haben wenigstens die nötigen Bordmittel um sowas umzusetzen.

    Das, was @ShredderButtonOn versucht zu "kippen" sieht für mich fast aus, wie Vectoring (aus der Mathe, kann mich irren) und mit Bash kannst du da auch nicht viel anfangen.

    Das bedeutet aber nicht, dass ich schlecht in irgendwelcher Programmiersprache bin, weil ich ein Array nicht umgedreht kriege, weil ich von Mathe nicht viel verstehe.

    Und ich kann immer und immer wieder betonen, dass der One-Liner nicht gut ist. Und Schadcode ist.

    EDIT: Solange du bei dem xargs Kommando kein initiales Kommando angibst, wird kein zusammengetrimmter Bullshit ausgeführt, sondern agiert wie echo. Also doch kein Schadcode.Du Herangehensweise finde ich trotz allem immer noch ziemlich umstritten.

    Das, was @wob sagte. ls -d */ und überhaupt ls soll man in Bash Scripts nie verwenden. Es sei denn du benutzt das Flag -1 noch dazu, das gibt dir jeden Ordner einzig und allein in einer Zeile. Daraus kannst du ein Array erzeugen und es dir anschaulich machen wie du willst. Und es geht noch besser: Das ls brauchst du überhaupt nicht. Mit diesem One-Liner:

    printf '%s %s %s %s %s\n' */
    

    listest du jeden Ordner in einer 5-Kolonnnen-Struktur.



  • Ich habe jetzt schon das nächste Problem. 😥

    find prefix* -mindepth 3 -name '*.ending' | xargs -I {} mv -v {} ..

    Ich möchte, alle Dateien mit Endung .ending, die in der dritten Ebene liegen, eine Ebene weiter nach oben verschieben, ausgehend vom jeweiligen Dateiverzeichnis.

    Beispiel

    pwd = .
    Datei 1 = ./a/b/c/x.ending
    Datei 1 nach Verschiebung = ./a/b/x.ending
    Datei 2 = ./d/b/c/x.ending
    Datei 2 nach Verschiebung = ./d/b/x.ending

    Problem

    Das .. bezieht sich aber immer auf das aktuelle basis wd (also .) ...

    Hat jemand vielleicht eine Idee? Datei 1 und 2 können nicht absolut/voll adressiert werden, da die "Unterverzeichnisstruktur" ja bei jeder Datei unterschiedlich ist.

    Nach einer kurzen Suche auf StackO wurde ich (noch) nicht fündig.


  • Mod

    Du könntest dirname auf den Dateinamen anwenden, dann wieder /.. anhängen. Gibt bestimmt auch irgendwelche anderen tollen Tricks mit %, aber die Syntax dafür ist mir zu fummelig. Ungefähr so sollte das gehen:

    find prefix* -mindepth 3 -name '*.ending' -exec bash -c 'mv "{}" $(dirname "{}")/..' \;
    

    Und jetzt möge @siri bitte kommen und genau erklären, was ich hier wo warum wie gequotet habe. Und wieso ich -exec genommen habe, und wieso ich darin ein bash -c mache, anstatt das mv direkt im exec zu machen. Laut siris Aussagen im Thread Bash vs. Powershell sind Bash-Quotingregeln schließlich ganz einfach.


  • Mod

    @siri sagte in [BASH: Tabelle mit 5 Spalten aus

    Das, was @wob sagte. ls -d */ und überhaupt ls soll man in Bash Scripts nie verwenden.

    Genau das hat wob ja gerade nicht vorgeschlagen. Lesen! Verstehen!



  • @SeppJ Danke!



  • @SeppJ muss ich dir jetzt etwas beweisen?

    Man soll eh kein bash -c in einem find machen. Warum wollt ihr auch eigentlich immer alles in eine einzige Zeile quetschen? Durch bestimmtes Quoting, indem du versuchst Bash-Ausdrücke in deinem -c Switch anzugeben wird das Argument zum ersetzen nicht von find übernommen, was daraus resultiert, dass auch genau der String {} als Argument verwendet wird.

    Man kanns sich halt auch einfacher machen. Du kannst dir eine Liste an Dateinamen erzeugen und einfach darüber iterieren, das ist dann zwar kein One-Liner mehr, jedoch viel übersichtlicher:

    mapfile -t files < <(find "$1" -maxdepth 3 -name '*.ending')
    
    for file in "${files[@]}"; do
        echo "${file}" "$(dirname "${file}")/.."
        # echo "${file}" "${file%/*}/.."
    done
    

    Du hast in deiner find Expression übrigens das Quoting rundherum $(...) vergessen. Und wie gesagt, bash -c sollte man bei find nicht machen.

    Bemerke auch das mapfile das ich verwendet habe, um ein Line-basiertes Array zu erstellen und ein Bash-internes Kommando ist und man solche Ausdrücke wie files=("$(find ...)") vermeiden soll.

    Was das Quoting angeht, kannst du diese einfach verschachteln, so wie in meinem Beispiel "$(dirname "${file}")/..". Viel mehr ist es nicht.

    EDIT: Außerdem würde ich hier auch kein dirname verwenden, sondern "${file%/*}/..". Das wäre noch pfiffiger und du ersparst dir obendrein noch einen Prozess.


Anmelden zum Antworten