Angeregt von Collections-Funktionen in Scala suchte ich in der Bash etwas, das ohne Sonderzeichen Argumente nach Position aus der Pipeline auswählt.
Bahnhof?
Ok, ein Beispielblock:
1 2 3 4 5 6 7 8 9 10 | t530:~/proj/mini/forum 🐧> uname -a Linux t530 5.4.0-88-generic #99-Ubuntu SMP Thu Sep 23 17:29:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux t530:~/proj/mini/forum 🐧> uname -a | take 5 Linux t530 5.4.0-88-generic #99-Ubuntu SMP t530:~/proj/mini/forum 🐧> uname -a | drop 5 Thu Sep 23 17:29:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux t530:~/proj/mini/forum 🐧> uname -a | drop 5 | take 6 Thu Sep 23 17:29:00 UTC 2021 t530:~/proj/mini/forum 🐧> uname -a | take 11 | drop 5 Thu Sep 23 17:29:00 UTC 2021 |
Ich weiß, der klassische Weg ist hier awk:
1 | uname -a | awk '{ print $6" "$7" "$8" "$9" "$10" "$11 }' |
Auch dachte ich mal, einen Weg gesehen zu haben, mit Syntax einen Arraybereich auswählen zu können, also in Pseudocode sowas zu schreiben:
1 2 | arr=($(uname -a)) echo ${arr[{5..11}]} |
aber mich trügt wohl die Erinnerung, oder ich habe es nirgends gefunden.
Praktisches Einsatzgebiet sind geschwätzige Programme, die keinen Schalter haben, um Überschriften etc. auszuschalten:
1 2 | wc -l demo.sh 32 demo.sh |
wobei wc nicht das beste Beispiel ist, da man es mit cat überlisten kann:
1 2 | cat demo.sh | wc -l 32 |
Hier lässt sich dann das Ergebnis einfach auffangen und damit weiterarbeiten.
Die Scripte take.sh und drop.sh sind nicht sehr elegant oder optimiert, aber tun was sie sollen. Einen Schalter, um den Delimiter festzulegen haben sie nicht, keine manpage, keine --version info. Gedacht sind sie als Shellfunktionen, die man in der .bashrc o.ä. sourced. take.sh:
1 2 3 4 5 6 7 8 9 10 11 12 | #!/bin/bash take () { read zeile; arr=($zeile); for ((i=0; i < $1; i+=1)) do echo -n "${arr[i]} "; done; echo } |
Hier das vergleichbar monströse drop, aber das liegt daran, dass es einen Kommentar enthält, der sich weitgehend mit diesem Posting deckt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/bin/bash # # Problemlage: # zwei Versionen des Programms syntrax liegen vor: # # > whereis syntrax # > syntrax: /usr/local/bin/syntrax /home/stefan/bin/syntrax # # Man würde nun gerne mit (tk)diff die Unterschiede sehen - dazu müsste man das störende, erste Wort "syntrax:" loswerden # whereis bietet selbst leider keinen Schalter an. # Die typische Lösung i.d. Linuxshell sieht so aus: # # > tkdiff $(whereis syntrax | awk '{print $2, $3}') # # Geschweifte Klammern, Apostrophe, Fingergymnastik. Wieos gibt es kein drop? # # Ziel ist es, tippen zu können: # # tkdiff $(whereis syntrax | drop 1) # # Here we go. This program is licensed under the GPLv3 # drop () { read zeile arr=($zeile) for ((i=$1; i < ${#arr[@]}; i+=1)) do echo -n ${arr[i]}" " done echo } # todo: check, whether called with param. If so, execute, else probably a sourcing (( $# == 1 )) && drop $1 |
Beides ist GPLv3. Im ersten könnte ich auch noch etwas wie einen Programmaufruf für das Argument, so eins da ist, ergänzen. Aber im Moment bin ich sehr beschäftigt.