Im Shell-Skript auf bestimmte Zeile und Spalte zugreifen wie?

4 Antworten

Hallo

der Inhalt der Datei sieht so aus wie auf dem Foto.
  1. Das hier ist nicht die Hausaufgabenhilfe.
  2. Und das Du zu faul bist die 6 Zeilen hier zu schreiben macht mich sauer, ich verabscheue Faulheit zutiefst und empfinde es als Beleidigung.
Beispielsweise möchte ich auf die Zeichenkette „schlechtes“ in der zweiten Zeile zugreifen und den Inhalt in einer variablen speichern.

Dafür ist grep in Verbindung mit cut und awk geeignet.

grep Allgemein wetterdaten.txt | awk '{print $3}'

oder gleich auf grep verzichten und statt dessen nur awk benutzen:

awk '/Allgemein/ {print $3}' wetterdaten.txt

Möchte man die Ausgabe nun in eine Variable mit dem Namen ALLGEMEIN speichern, dann ginge das zum Beispiel so:

ALLGEMEIN=$(awk '/Allgemein/ {print $3}' wetterdaten.txt)
echo $ALLGEMEIN

Natürlich gibt es auch noch andere Möglichkeiten.

Die Zeichenkette sind immer mit genau einem Tabulator getrennt.

Was es für cut wesentlich umständlicher macht :-(

Da könnte man natürlich die Tabulatoren vorher mit sed in Leerzeichen wandeln und die dann mit uniq die überzähligen entfernen: lassen bevor man cut dran lässt.

sed 's/\t/ /g' wetterdaten.txt | uniq | grep Allgemein | cut -d' ' -f2

Da ist es mit awk dann doch einfacher. Es soll auch echte perl Künstler geben die es damit umsetzen - ich bin keiner.

Linuxhase

Woher ich das weiß:eigene Erfahrung – Ich benutze seit 2007 Linux und habe LPIC101 und LPIC102
salvatoreleone 
Fragesteller
 28.12.2019, 19:49

erstmal danke für die Hilfe 👍🏻

aber

welcher Schüler hat bitte als Unterrichtsthema Shell-Programmierung? Also Nein das sind keine Hausaufgaben

und wenn du es als Beleidigung auffasst, dass ich wegen der Übersichtlichkeit einfach die Tabelle abfotografiert habe und du aus dieser Mücke gleich nen 3 Zeiler machst, kann ich dir auch nicht mehr helfen

0
Linuxhase  28.12.2019, 20:22
@salvatoreleone
welcher Schüler hat bitte als Unterrichtsthema Shell-Programmierung? Also Nein das sind keine Hausaufgaben

Es gibt tatsächlich Berufsausbildungen wo solche Dinge benötigt werden, also auch in der Berufsschule oder dem Studio.

wegen der Übersichtlichkeit einfach die Tabelle abfotografiert habe

Findest Du das nachfolgende nun weniger übersichtlich?

Tag             Heute           Morgen          Uebermorgen     Am_Wochenende
Allgemein       schoenes        schlechtes
Temperatur      5               10              20              30              40
Regen           kein            leichter        Niesel-         starker         Eis-
Wind            kein            leichtr         starker         boeiger         stuermischer    orkanartiger
Sonne           keine           kaum    etwas   viel

Erweitere Deinen Horizont und benutze den Kopf zum denken.

Linuxhase

0
salvatoreleone 
Fragesteller
 28.12.2019, 21:11
@Linuxhase

es Ist auf keinen Fall übersichtlicher und schon ein wenig unschöner

nur finde ich es viel erbärmlicher sich deswegen aufzuregen.. vielleicht sollte jemand anderes mal den Horizont überprüfen. Es gibt da so ein schönes Wort namens „weltfremd“...

2
result="$(awk 'NR==<zeile> {printf $<spalte>}' <datei>)"

Ersetze <zeile>, <spalte> und <datei> durch die passenden Werte. Anschließend kannst du auf die Variable result zugreifen.

salvatoreleone 
Fragesteller
 28.12.2019, 12:16

Danke, genau so hab ich mir das vorgestellt

1
Linuxhase  28.12.2019, 17:58

Das sieht aber nicht so schön aus:

linuxhase@Linuxhase-Desktop ~$ awk 'NR==2 {printf $2}' wetterdaten.txt
schoeneslinuxhase@Linuxhase-Desktop ~$

Wird aber die Variable nicht stören ;-)

Linuxhase

0
Linuxhase  28.12.2019, 18:55
@verreisterNutzer
Ich glaub deine Shell ist kaputt.

Meinst Du:

bash --versionGNU bash, Version 5.0.11(1)-release (x86_64-pc-linux-gnu)Copyright (C) 2019 Free Software Foundation, Inc.Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl.html>
Dies ist freie Software. Sie darf verändert und verteilt werden.
Es wird keine Garantie gewährt, soweit das Gesetz es zulässt.

Aber auch mit einer anderen Shell, hier ksh, der gleiche Effekt:

linuxhase@Linuxhase-Desktop ~$ ksh
$ awk 'NR==2 {printf $2}' wetterdaten.txt
schoenes$

oder dash

linuxhase@Linuxhase-Desktop ~$ dash
$ awk 'NR==2 {printf $2}' wetterdaten.txt
schoenes$
Versuch es mal mit printf :)

Und ich habe Dein Kommando immer so verwendet wie Du geschrieben hast.

Linuxhase

0
verreisterNutzer  28.12.2019, 18:58
@Linuxhase

Bei mir kommt eine andere bash Version heraus:

GNU bash, Version 5.0.3(1)-release (x86_64-pc-linux-gnu)
ich habe Dein Kommando immer so verwendet wie Du geschrieben hast.

Bitte aufpassen. Nicht das hier noch ein Hacker seinen Hacker-Code veröffentlicht und du den blind ausführst.

0
Linuxhase  28.12.2019, 19:18
@verreisterNutzer
Bei mir kommt eine andere bash Version heraus:

Meine installierten sind diese hier:

dash 0.5.10.2-2
ksh 2020.0.0-1
bash 5.0.011-2

Ich glaube aber nicht das es an der Version der jeweils verwendeten Shell liegt ;-)

Bitte aufpassen. Nicht das hier noch ein Hacker seinen Hacker-Code veröffentlicht und du den blind ausführst.

Das wird ganz sicher nicht passieren!

Linuxhase

0
verreisterNutzer  28.12.2019, 19:23
@Linuxhase

Ich nutze:

bash 5.0.3
tcsh 6.20.00
dash 0.5.10.2

Die ksh nutze ich gar nicht. Ich hab aber gehört, die soll einige Vorteile haben.

1
barnim  29.12.2019, 18:29
@Linuxhase
Das sieht aber nicht so schön aus:

Sieht so aus wie man das eigentlich will, ohne \n der \r\n

1

Eine Pipe aus grep und awk.

Woher ich das weiß:Hobby – Langjähriger PC-Spieler und -Bastler
Linuxhase  28.12.2019, 17:50

oder gleich auf grep verzichten und alles von awk machen lassen ;-)

1

Nebn awk kannst DU auch Dinge wie head, tail, cut, grep usw. nutzen.

Linuxhase  28.12.2019, 17:55

Du meinst so:

head -n2 wetterdaten.txt | tail -n1 | awk '{print $2}'

Geht natürlich auch, ist aber nicht besonders effektiv und schnell.

linuxhase@Linuxhase-Desktop ~$ time head -n2 wetterdaten.txt | tail -n1 | awk '{print $2}'
schoenes

real    0m0,006s
user    0m0,008s
sys     0m0,006s
linuxhase@Linuxhase-Desktop ~$ time sed 's/\t/ /g' wetterdaten.txt | uniq | grep Allgemein | cut -d' ' -f2
schoenes

real    0m0,006s
user    0m0,009s
sys     0m0,004s
linuxhase@Linuxhase-Desktop ~$ time awk '/Allgemein/ {print $3}' wetterdaten.txt
schlechtes

real    0m0,006s
user    0m0,003s
sys     0m0,003s

Linuxhase

0
KarlRanseierIII  28.12.2019, 19:32
@Linuxhase

Ja, wobei Du genausogut cut statt awk nehmen könntest. cut sollte schneller spawnen.

Und ja, 3 spawns sind natürlich teurer als direktes awk-en.

Die Frage ist natürlich, wie häufig das Gesamtkonstrukt verwendet wird, also in welche Frequenz.

Man könnte es natürlich auch komplett als Shellscript machen, wenn man wollte.

Letztlich ging es nur darum weitere Optionen aufzuzeigen, in anderen Fällen kann die Kenntnis von tail, head und Co. durchaus praktisch sein :-D.

0
Linuxhase  28.12.2019, 20:12
@KarlRanseierIII
Ja, wobei Du genausogut cut statt awk nehmen könntest. cut sollte schneller spawnen.

Tut es aber nicht:

time head -n2 wetterdaten.txt | tail -n1 | cut -d' ' -f2
Allgemein      schoenes       schlechtes

real   0m0,005s
user   0m0,001s
sys    0m0,009s
Die Frage ist natürlich, wie häufig das Gesamtkonstrukt verwendet wird, also in welche Frequenz.

Das stimmt schon, aber es spricht ja nichts dagegen dennoch Effizient zu schreiben :-)

Letztlich ging es nur darum weitere Optionen aufzuzeigen, in anderen Fällen kann die Kenntnis von tail, head und Co. durchaus praktisch sein :-D.

Das ist auch richtig und gut von Dir :-)

Es wird früher oder später immer Gelegenheiten geben bei denen man diese kleinen Helferlein brauchen kann.

Linuxhase

1
Linuxhase  28.12.2019, 20:16
@Linuxhase
linuxhase@Linuxhase-Desktop ~$ time head -n2 wetterdaten.txt | tail -n1 | sed 's/\t/ /g'| cut -d' ' -f2
schoenes

real    0m0,005s
user    0m0,011s
sys     0m0,004s
1
verreisterNutzer  28.12.2019, 22:53
@Linuxhase

Am besten auch noch einmal in C programmieren und im Compiler die passenden Flags zur Optimierung setzen, wenn die interpretierte Variante zu langsam ist.

1
KarlRanseierIII  28.12.2019, 23:07
@verreisterNutzer

Vorher aber noch PERL und Python, ich meine, awk, schön und gut, aber es ist nicht so toll von der Ausdruckskraft, also gleich die Kanonen auspacken :-D.

1