Im Shell-Skript auf bestimmte Zeile und Spalte zugreifen wie?
Hallo Leute,
ich möchte einer Datei zugreifen.
der Inhalt der Datei sieht so aus wie auf dem Foto. Beispielsweise möchte ich auf die Zeichenkette „schlechtes“ in der zweiten Zeile zugreifen und den Inhalt in einer variablen speichern. Wie kann ich genau auf dieses einzelne Feld zugreifen? Die Zeichenkette sind immer mit genau einem Tabulator getrennt.
gibt es dafür einen extra Befehl?
4 Antworten
Hallo
der Inhalt der Datei sieht so aus wie auf dem Foto.
- Das hier ist nicht die Hausaufgabenhilfe.
- 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
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
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“...
Je besser die Qualität der Frage ist, desto mehr Mühe geben sich die potentiellen Antwortgeber.
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.
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
Ich glaub deine Shell ist kaputt. Versuch es mal mit printf :)
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
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.
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
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.
Das sieht aber nicht so schön aus:
Sieht so aus wie man das eigentlich will, ohne \n der \r\n
Eine Pipe aus grep und awk.
Nebn awk kannst DU auch Dinge wie head, tail, cut, grep usw. nutzen.
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
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.
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
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
Am besten auch noch einmal in C programmieren und im Compiler die passenden Flags zur Optimierung setzen, wenn die interpretierte Variante zu langsam ist.
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.
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