Arrays in der bash

  • Ersteller Mr.VamosMuchach
  • Erstellt am
M

Mr.VamosMuchach

Grünschnabel
Hallo zusammen

Dies ist mein erster Beitrag. Ich hoffe auf eine gute Antwortenrate :D

Also zu meiner Frage:
Ich habe ein 2 Scripts geschrieben, die folgende Ausgabe erzeugen:
Code:
 ATSRV003_SQL                19.36
ATSRV005                    47.70
ATSRV005_SQL                 0.77
ATSRV010                    48.80
ATSRV011                    53.85
ATSRV011_SQL             19327.65
ATSRV019                    46.76
ATSRV020                    86.55
ATSRV020_SQL                53.54
ATSRV022                   211.13
ATSRV024                    47.09
ATSRV025                    49.81
ATSRV026                    57.57
ATSRV035                    82.35
ATSRV035_SQL              1621.71
ATSRV037                  6786.68
ATSRV038                 10411.82
ATSRV042                    45.32
ATSRV042_SQL               653.13
ATSRV045                  1822.24
ATSRV047                    83.24
ATSRV047_SQL              2173.18
ATSRV048                    61.53
ATSRV048_SQL               188.24
ATSRV049                   207.88
ATSRV049_SQL                60.38
ATSRV050                    61.26
ATSRV056                    39.37
ATSRV056_SQL                 3.27
ATSRV057                    57.92
ATSRV060                    69.09
ATSRV062                   105.05
ATSRV062_SQL               194.16
ATSRV065                     9.28
ATSRV065_SQL                10.06
ATSRV071                    52.18
ATSRV071_SQL                10.24
ATSRV072                    53.62
ATSRV077                    39.38
ATSRV079                    51.24
ATSRV079_SQL                 4.71
ATSRV084                   280.19
ATSRV084_SQL                 1.80
ATSRV085                    61.68
ATSRV086                   673.19
ATSRV087                   213.28
ATSRV090                   194.29
ATSRV092                    42.82
ATSRV092_SQL               263.94
ATSRV093                   659.35

Code:
DATABASE                                        18033.75
EXCHANGE                                          333.95
NOTES                                             333.95
SAP                                              7681.04
UNIX                                            20371.46
WINDOWS                                         39073.13

Links sind Servernamen und rechts deren Grösse.
ich möchte nun dass es diese so umformatiert:
Code:
 Servername Servername Servername Servername
          Servergrösse Servergrösse Servergrösse Servergrösse


Ich dachte ich mache es mit einem Array.
Folgendes Problem habe ich:
1. Wie kann ich 1 Script schreiben, das bei allen solchen Ausgaben funktioniert, bzw. dass es die erste Spalte als Namen erkennt und die zweite Spalte als Servergrösse?

Das ganze soll so formatiert werden, damit ich mit gnuplot eine Auswertung des Serverwachstums machen kann.

Danke und Gruss
 
Ohne bestimmte Formatierung der Ausgabe sollte das so funktionieren.

Code:
#!/bin/bash
typeset -i x=0
while read input
  do
      VAR1[x]=$(echo $input | awk '{ print $1 }')
      VAR2[x]=$(echo $input | awk '{ print $2 }')
      (( x = x + 1 ))
done < input-datei.txt

echo ${VAR1[*]}
echo ${VAR2[*]}
 
Danke!

Danke!!!:):):):):):):):):)

Aber ich habe noch eine Frage:
Code:
typeset -i x=0
while read source /users/athaeses/tmp/all/test.txt
  do
      VAR1[x]=$(echo $input | awk '{ print $1 }')
      VAR2[x]=$(echo $input | awk '{ print $2 }')
      (( x = x + 1 ))
done < source /users/athaeses/bin/usageall.sh-datei.txt

echo ${VAR1[*]}
echo ${VAR2[*]}

geht das so?

Was macht eigentli das
Code:
done <
?
 
geht das so?

Was macht eigentli das
Code:
done <
?

das "done" schliesst die while-schleife ab und das "<" schiebt den Inhalt der datei in diese Schleife.
Was soll das "source" vor deiner datei?
Ist nicht nötig, oder besser, darf nicht sein.
Nur der Dateiname!

Oh, und ich sehe gerade....

Das "input" in meinem Beispiel ist ein Variablenname, kein Hinweis auf deine Datei.
Außer dem Dateinamen nach dem "done < ..." bitte alles so lassen, wie es da steht.
 
Danke viel mals!! Ich bin noch ein Informatiklernender (1. Lehrjahr).
Leider verstehe ich den ganzen Code noch nicht ganz. Ich versuche es mal zu analysieren:

Code:
#!/bin/bash
typeset -i x=0
while read input

Was macht das typeset -i x=0?
While read input heisst doch dass das nachfolgende in die Variabel input geschrieben wird.


Code:
do
      VAR1[x]=$(echo $input | awk '{ print $1 }')
      VAR2[x]=$(echo $input | awk '{ print $2 }')
      (( x = x + 1 ))
done < input-datei.txt

erstelle die Variabel VAR1 [was macht das x?] Nimm den Inhalt von der Variabel input und von diesem soll es von jeder Zeile das erste Wort irgendwo hineinschreiben (Wo genau?)
Dann das Gleiche nochmals.

nach jedem Durchgang zählt wird x um 1 erhöht. Warum? Oder bewirkt dies, dass es die Schleife verlässt, wenn x den Wert 2 bzw. 3 erhält?
Das done beendet die Schleife. Das < nimmt die Ausgabe des andern, bereits geschriebenen Scripts bzw. eine .txt- Datei mit der Ausgabe des Scripts?


Code:
echo ${VAR1[*]}
echo ${VAR2[*]}
es gibt die Variabeln aus. Das * ist eine Wildcard nehme ich an. Aber wofür?

DANKE!! Du/Sie bist/sind eine grosse Hilfe!!!
 
Was macht das typeset -i x=0?
Es definiert die Variable x mit dem initialen Wert 0 als Integer.
Interger weil das die Variable ist, die im Array als Zähler benutzt wird.

Code:
While read input
Geanuer heißt es, lese von stdin zeilenweise ein.
stdin wird später durch das "done < file.txt" gefüllt. ;-)

Code:
do
      VAR1[x]=$(echo $input | awk '{ print $1 }')
      VAR2[x]=$(echo $input | awk '{ print $2 }')
      (( x = x + 1 ))
done < input-datei.txt
Also, while read input liest solange zeilenweise aus input-datei.txt bis Ende.
Erster Teil des ersten Wertes (dein Hostanme) wird in Variable VAR1[0] geschrieben (im Arbeitsspeicher), zweiter Teil des ersten Wertes wird in Variable VAR2[0] geschrieben.
Zähler x wird um 1 erhöht. Gültige Array Variable ist jetzt 1.
Nächste zeile wird eingelesen.
Erster Teil des zweiten Wertes wird in VAR1[1] geschrieben und zweiter Teil des zweiten Wertes wird in VAR2[1] geschrieben, und so weiter.
Die Schleife wird erst verlassen, wenn alle Zeilen eingelesen wurden. (Dateiende)
Code:
echo ${VAR1[*]}
echo ${VAR2[*]}
es gibt die Variabeln aus. Das * ist eine Wildcard nehme ich an. Aber wofür?

Des eben geschrieben Arrays. * sind alle Werte von 0 bis n.


DANKE!! Gern geschehen, und das Du ist gebräuchlich hier. ;-)
 
Zuletzt bearbeitet:
Also das heisst es muss die Variabel erhöhen dass es im Arbeitsspeicher eine neue "notiz" macht und die bereits gemachte nicht einfach überschreibt? Bzw. dem Array etwas weiter hinzufügt?
Ist ja extream ähnlich mit Java :-)

DANKE VIEL MALS!!!
 
Das script macht keinerlei Fehlerüberprüfung, ob die Inputdaten ok waren oder überhaupt verfügbar sind.

Möglich wäre da noch ein
Code:
if [ ! -f input-datei.txt ]
 then
exit 99
fi
vor der while-schleife.
Und ein
Code:
if [ ${#VAR1[*] -ne ${#VAR2[*]} ]
then
  echo "Datenanzahl sind ungleich! EXIT"
  exit 98
else
 echo ${VAR1[*]} > output.txt
 echo ${VAR2[*]} >> output.txt
ganz am Ende.

Da könnte man sich noch ganz andere Sachen einfallen lassen, aber für den Anfang wäre das eine kleine Sicherheit, dass keine "schlechten" Daten verarbeitet werden.
 
Also:
Wenn [ der Input NICHT dieser Datei entspricht ] (was macht das -f)?
dann
beende das Script




wenn [ die Variabeln -ne (nicht existieren?) ]
dann
gib den text aus und beende das script.
sonst schreibe die Variabeln in die angegebenen Dateien.


Wie kann ich machen dass es z.B die Ausgaben in eine Datei schreibt?
 
Also:
Wenn [ der Input NICHT dieser Datei entspricht ] (was macht das -f)?
dann
beende das Script
Natürlich bezieht sich der Input auf deine datei, aber in deinem Beispiel hast du
Code:
while read source /users/athaeses/tmp/all/test.txt
geschrieben.
Das geht so nicht.
Bei mir habe ich die Variable, die während des Schleifendurchlaufs eingelesen wird, "input" genannt, du kannst sie auch "line" oder "mausi" nennen.
Allerdings muss dieser Variablenname dann in
Code:
VAR1[x]=$(echo $input | awk '{ print $1 }')
auch benutzt werden.
Und das "-f" ist ein Schalter des "test" commands und steht für "True if file exists and is a regular file."



wenn [ die Variabeln -ne (nicht existieren?) ]
dann
gib den text aus und beende das script.
sonst schreibe die Variabeln in die angegebenen Dateien.
-eq bedeutet "not equal"
Die Anzahl der Arrayeinträge wird verglichen und falls nicht gleich, beende das script.

Wie kann ich machen dass es z.B die Ausgaben in eine Datei schreibt?

Mit den Umlenkungszeichen der shell: < >
Mehr dazu in dem Link von tuxlover, der von dir unbedingt mal beachtet werden sollte.
 
Okay danke viel mals nochmal!!

Ich habe jetzt folgenden Code:
Code:
#!/bin/bash

# testen ob die Input- Datei vorhanden, bzw. korrekt ist ist.
if [ ! -f /users/athaeses/tmp/all/test.txt ]
        then

        # Wenn dies nicht der Fall ist, dann das Script beenden
        exit 99
fi




# Variable x mit dem Anfangswert 0 definieren.
typeset -i x=0

# Den spaeter folgenden Input zeilenweise einlesen. Das Input hier ist eine Variabel.
while read input

do
        # Der Erste Teil des ersten Wertes (in diesem Fall der Hostname) in die Variable VAR1[0] schreiben.
        VAR1[x]=$(echo $input | awk '{ print $1 }')

        # Der zweite Teil des ersten Wertes (in diesem Fall die Speichergroesse) in die Variable VAR2[0] schreiben.
        VAR2[x]=$(echo $input | awk '{ print $2 }')

        # Zaeler der Variabel um 1 erhoehen, damit es einen neuen Array bildet.
        (( x = x + 1 ))

# Die naechste Zeile einlesen

# Input- Datei angeben. Die Schleife verlassen, wenn alle Zeilen eingelesen wurden.
done < /users/athaeses/tmp/all/test.txt

# Alle Arrays die erstellt wurden ausgeben.
echo ${VAR1[*]}
echo ${VAR2[*]}
 
So sollte das grundsätzlich funktionieren.
Vielleicht noch eins:

Code:
#!/bin/bash
# input file definieren
if [ -z ${1} ]
 then
     INPUT_FILE="/users/athaeses/tmp/all/test.txt"
else
     INPUT_FILE="${1}"
fi
# Variable x mit dem Anfangswert 0 definieren.
typeset -i x=0
# testen ob die Input- Datei vorhanden, bzw. korrekt ist ist.
if [ ! -f ${INPUT_FILE} ]
        then

        # Wenn dies nicht der Fall ist, dann das Script beenden
        exit 99
fi




# Variable x mit dem Anfangswert 0 definieren.
typeset -i x=0

# Den spaeter folgenden Input zeilenweise einlesen. Das Input hier ist eine Variabel.
while read input

do
        # Der Erste Teil des ersten Wertes (in diesem Fall der Hostname) in die Variable VAR1[0] schreiben.
        VAR1[x]=$(echo $input | awk '{ print $1 }')

        # Der zweite Teil des ersten Wertes (in diesem Fall die Speichergroesse) in die Variable VAR2[0] schreiben.
        VAR2[x]=$(echo $input | awk '{ print $2 }')

        # Zaeler der Variabel um 1 erhoehen, damit es einen neuen Array bildet.
        (( x = x + 1 ))

# Die naechste Zeile einlesen

# Input- Datei angeben. Die Schleife verlassen, wenn alle Zeilen eingelesen wurden.
done < ${INPUT_FILE}

# Alle Arrays die erstellt wurden ausgeben.
echo ${VAR1[*]}
echo ${VAR2[*]}

Wenn du mal eine andere Datei einlesen willst, kannst du sie direkt beim script-aufruf als Argument angeben, sonst nimmt er die definierte Datei.
Außerdem brauchst du, falls sich der Dateiname mal ändert, das nur noch an einer Stelle im script ändern.
 

Ähnliche Themen

Frage zu Bash Script mit Grep Ausgabe

Samba 4 Gast Zugang unter Ubuntu funktioniert nicht

Last mit etc/passwd anzeigen lassen

suchen und ersetzen, Format erhalten

Probs mit Perl script

Zurück
Oben