Datei zeilenweise und spaltenweise auslesen

O

onlineuser

Mitglied
Hi,

ich habe folgendes Problem. Möchte gerne eine Datei zeilenweise auslesen und dabei jede Zeile in zwei Spalten aufteilen.

Mache ich das am besten in einer for-Schleife, jedoch wann weiß ich, wann ich am Ende der Datei bin? awk bietet ja eine Möglichkeit die Zeile x zurückzuliefern. Jedoch wie stelle ich die maximale Zeilenanzahl einer Datei fest, damit die for-Schleife dann auch aufhört!?

Oder gibt es da eine geschicktere Möglichkeit?

Liebe Grüsse.
 
onlineuser schrieb:
Hi,

ich habe folgendes Problem. Möchte gerne eine Datei zeilenweise auslesen und dabei jede Zeile in zwei Spalten aufteilen.
An welchem Zeichen sollen diese denn getrennt werden?
Was willst du als Spaltentrenner verwenden?
onlineuser schrieb:
Mache ich das am besten in einer for-Schleife, jedoch wann weiß ich, wann ich am Ende der Datei bin? awk bietet ja eine Möglichkeit die Zeile x zurückzuliefern. Jedoch wie stelle ich die maximale Zeilenanzahl einer Datei fest, damit die for-Schleife dann auch aufhört!?

Oder gibt es da eine geschicktere Möglichkeit?

Liebe Grüsse.
Das Ende der Datei wird bei EOF erkannt, was auch gleichbedeutend ist mit dem Ende des Eingabestroms (die Eingabe liefert undef).

Was hast du bisher probiert?
Wo klappt etwas nicht?
Bring doch mal deinen Versuch und Beispieldaten deiner Datei.
wenn du z.B. eine datei mit zwei Worten pro zeile hast, die du mit einem tab getrennt ausgeben willst, dann kannst du mit sed, perl, awk... arbeiten.
Beispiel mit sed wobei das erste Wort vom zweiten statt Leerzeichen durch Tab getrennt ausgegeben wird. Alles danach wird unterdrückt:
sed -e ' s/^\([^ ]*\) \([^ ]*\) .*$/\1\t\2/' eingabe_datei >ausgabe_datei
oder mit awk:
awk '{print $1"\t"$2}' eingabe_date >ausgabe_datei
mit perl
perl -ane 'print "$F[0]\t$F[1]\n"' eingabe_datei >ausgabe_date
usw...
reine bash:
while read erstes zweites dummy; do echo -e "$erstes\t$zweites" >>ausgabe_datei; done <eingabe_datei

Also bring mal ein paar Beispieldaten und was du versucht hast.

Gruß Wolfgang
 
Zuletzt bearbeitet:
Hi,

hab bisher diese Idee gehabt:

Code:
line=0
while true;
do
  line=$((line+1))
  cat guests.txt | awk ' NR == line { print $1 }' line="$line"
done

Funktionierte aber nicht, da es anscheinend eine Endlosschleife war.

Dachte, ich lese so jede Zeile aus. Das Trennzeichen zwischen den Spalten ist ein "#". Und ich möchte beide Spalten in einer HTML-Tabelle ausgeben (soll ein CGI-Script werden).

Brauche deshalb jede Zeile einzeln, damit ich es mit <tr><td>$spalte_1</td><td>$spalte2</td></tr> auffüllen kann.

Danke für deine Anregungen. Werde mal weiter grübeln! *gg*

So, habs jetzt so gelöst:

Code:
while read line
do
spalte_1=$(echo $line | cut -d "#" -f 1)
spalte_2=$(echo $line | cut -d "#" -f 2)
echo "<tr><td>$spalte_1</td><td>$spalte_2</td></tr>"
done < "guests.txt"

Funktioniert so! Natürlich wäre eine Funktion, die eine beliebige Anzahl von Spalten in ein <td>...</td> Gerüst einfügt feiner und universeller, aber das ist in meinem Fall nicht notwendig.

Liebe Grüsse.
 
Zuletzt bearbeitet:
Hallo,

ja, Deine Lösung geht, aber es ist etwas umständlich und ressourcenhungrig, weil Du viele zusätzliche Prozesse brauchst (als ob das bei den modernen Rechnern heute noch jemanden interessiert ;-)

Ich hätte es wahrscheinlich so, gemacht, dass ich den Trenner (also das "#") gleich als internen Feldtrenner verwendet hätte:

Code:
IFS='#'
while read spalte_1 spalte_2 ;
do
    echo  "<tr><td>$spalte_1</td><td>$spalte_2</td></tr>"
done < guests.txt

Das spart Dir die ganzen Zwischenschritte (Speichern in Variablen, die ganzen zusätzlichen echos und cut-Aufrufe).

Just my 2 cents
 
Hi,

hab noch eine Frage zur For-Schleife. Und zwar bekomme ich per Post einen QueryString. Im HTML File waren die Wörter mit Leerzeichen getrennt. Im QueryString durch Post werden die Leerzeichen dann zu einem +.

Nun möchte ich in einer For-Schleife jedes Element durchgehen:

Code:
read -n $CONTENT_LENGTH QUERY_STRING
host=$(echo $QUERY_STRING | cut -d "=" -f 2)

for host2ping in ${host/+/ }
do
  echo $host2ping"<br>"
done

Jedoch teilt die For-Schleife nur nach dem ersten + ab, d.h.: es gibt 2 Durchläufe.

1+2+3+4 wird also zu 1 und 2+3+4

Wie kann ich den Separator für die For-Schleife festlegen? Und wieso teilt er nicht nach jedem + einen Durchlauf auf?

Standardmäßig teilt For nach Leerzeichen ab, aber warum wird bei mir nur das erste + durch ein Leerzeichen ersetzt!?

Sonst müßte ich alle + zählen, dann 1 addieren, dann hätte ich die Anzahl der Elemente, die im QueryString waren. Aber dann kam ich auf die Idee mit dem Separator.

Update:
Habe jetzt einfach die + mit Leerzeichen ersetzt, bevor es in die For-Schleife geht.
Code:
host=$(echo $host | tr "+" " ")

Trotzdem wäre es gut zu wissen, ob und wie man den Separator direkt in der For-Schleife festlegen kann!?

Liebe Grüsse.
 
Zuletzt bearbeitet:
Statt

Code:
...${host/+/ }...

nimm

Code:
${host//+/ }

Gruss, Xanti
 
Hi,

Danke!

Hätte noch eine Frage zum URL-Encoding.

Ein "\" wird beim Auslesen des GET-Parameters zu "%2F". Wenn ich nun mit filename=`echo $filename | tr '%2F' '\'` ersetze, dann schreibt er mir statt "%2F" drei "\" hin. Wie kann ich diese wieder auf eines reduzieren?

Geht das nicht irgendwie anders, dass Bash das URL-Encoding selbst und automatisch durchführt?

Update:

Ging ja doch mit tr! :)

Code:
filename=$(echo $filename | tr -s '%2F' '\')

Liebe Grüsse.
 
Zuletzt bearbeitet:

Ähnliche Themen

Dateien auslesen und Daten systematisch angeordnet in Datei ausgeben

Prblem mit zeilenweises auslesen von Datei und schreiben nach mysql

CSV Datei mit sed manipulieren/optimieren/ergänzen

Sehr große Datei in Teilschritten auslesen.

Zeilenweise auslesen und in Variable speichern / übergeben

Zurück
Oben