ubuntuusers.de

Nach Zahlenblock in einer Datei suchen

Status: Gelöst | Ubuntu-Version: Ubuntu 14.04 (Trusty Tahr)
Antworten |

ka111

Anmeldungsdatum:
22. Juni 2014

Beiträge: 141

Wie kann ich in einer Datei nach Zahlenblöcken suchen? Also wenn ich 2 Zahlenblöcke habe und noch ein paar Buchstaben dazwischen, kann ich irgendwie den ersten Zahlenblock heraus suchen und alles andere weg schneiden (mit grep und sed vielleicht)? Und dann denn zweiten suchen und alles andere weg schneiden?

Am Schluss sollten die 2 Zahlenblöcke in je einer Datei stehen. Also zB.

In einer Datei steht: ksdf:100ajkl:sd50

Dann sollte es 100 in eine Datei schreiben und 50 in eine andere. Wie kann ich das machen? (Es sind aber nicht immer zuerst 3 Zahlen und dann 2)

g00d.morning

Anmeldungsdatum:
20. Februar 2013

Beiträge: 330

Hi!

Was genau hast Du vor? Soll eine Datei Zeilenweise ausgelesen werden? Oder geht es um alle Zahlen in einer Datei? Spielt es eine Rolle, dass es "nicht immer drei Zahlen" sind???

sed kann Dir die Buchstaben wegschneiden.

echo "ksdf:100ajkl:sd50" | sed 's/[^0-9]/ /g'

Das kann man dann z.B. in eine Schleife packen:

1
2
3
4
for i in $(sed 's/[^0-9]/ /g' <inputfile>); do 
    c=$((c+1))
    echo $i > file$c.txt
done

Nur mal als Anregung, falls die komplette Datei gemeint ist und falls das (auch?) eine hypothetische Frage ist.

Grüße

ka111

(Themenstarter)

Anmeldungsdatum:
22. Juni 2014

Beiträge: 141

In einer Datei (sagen wir Datei0) steht 1 Zeile ohne Abstände, mit Buchstaben, :, und 2 Zahlenblöcken dazwischen. Es soll die 2 Zahlenblöcke einzel in je eine Datei schreiben, inder sonnst nichts anderes steht. Also der erste Zeilenblock in Datei1 und der zweite in Datei2.

Nein es spielt keine Rolle das es eigentlich 3 Zahlen sind, wollte nur sagen dass man nicht nach den ersten 3 suchen kann, weil es manchmal auch 2 am Anfang sind und 3 am Schluss.

Danke für die Anregung. Das ist jetzt schon wirklich, nicht nur hypothetisch ☺

(Ich könnte auch die Zeile so in die Datei schreiben dass die 2 Zahlenblöcke von Leerzeichen umgeben sind, aber am Schluss sollten nur die Zahlen in der Datei stehen)

g00d.morning

Anmeldungsdatum:
20. Februar 2013

Beiträge: 330

Wenn das alles so ist, wie Du schreibst, dann sollte meine "Anregung" bereits genau das machen 😉

ka111

(Themenstarter)

Anmeldungsdatum:
22. Juni 2014

Beiträge: 141

Ah ja, ich erhalte die 2 Blöcke ☺

Aber wie schreib ich jetzt die erste Zahl (Zahlenblock) in Datei1 und die zweite in Datei2?

... Aha, die "Anregung", muss ich kurz testen

Ah ja, dein Beispiel fügt den 2. Block in die von mir eingegebene Datei ein. Wie kann ich den ersten auch in eine Datei schreiben? (Sorry, ich habe vom programmieren nicht so Ahnung)

--EDITIERT

g00d.morning

Anmeldungsdatum:
20. Februar 2013

Beiträge: 330

ka111 schrieb:

Ah ja, dein Beispiel fügt den 2. Block in die von mir eingegebene Datei ein

"Eigentlich" nicht

1
2
3
4
for i in $(sed 's/[^0-9]/ /g' <inputfile>); do    # sed öffnet deine input-Datei und gibt zwei Zahlen aus, die in jedem Durchlauf (2x) für "i" eingesetzt werden
    c=$((c+1))                                    # Variable c wird in jedem Durchlauf einen hochgezählt
    echo $i > file$c.txt                          # i wird ausgegeben und in "file1.txt, file2.txt" geschrieben
done

PS. Kann es sein, dass Du statt echo $i > file$c.txt irgendeinen anderen Namen ohne $c verwendet hast? In diesem Fall wird die Datei (im zweiten Durchlauf der Schleife) überschrieben und tatsächlich nur die zweite Zahl bleibt stehen.

ka111

(Themenstarter)

Anmeldungsdatum:
22. Juni 2014

Beiträge: 141

Ah ja, ich dachte das ist nur ein Beispiel wie man immer wieder Datei1, Datei2, Datei3... automatisch schreiben kann. Jetzt funktiniert alles, danke 😀

Ich verstehs aber immer noch nicht wieso es die 2 Blöcke einzel in 2 Dateien schreibt, und nicht beide Blöcke in eine Datei. Wo ist da der Befehl der das macht? Wegen for .. in ...;do? Oder ist das schon in dem sed Befehl? Nur der sed befehl alleine gibt mir ja beide Zahlen aus, oder bedeuten die Abstände dazwischen dass es das nacher gleich so macht?

(Ist aber auch nicht so wichtig)

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13215

ka111 schrieb:

Ich verstehs aber immer noch nicht wieso es die 2 Blöcke einzel in 2 Dateien schreibt, und nicht beide Blöcke in eine Datei. Wo ist da der Befehl der das macht? Wegen for .. in ...;do? Oder ist das schon in dem sed Befehl? Nur der sed befehl alleine gibt mir ja beide Zahlen aus, oder bedeuten die Abstände dazwischen dass es das nacher gleich so macht?

Nein, es ist Zeile 3: der Dateinamen, der für die Ausgabeumleitung genutzt wird, wird bei jedem Schleifendurchlauf anders generiert (schau mal auf die Variable c).

g00d.morning

Anmeldungsdatum:
20. Februar 2013

Beiträge: 330

Aaalso:

Einmal das zur Lektüre: Shell/Bash-Skripting-Guide für Anfänger

sed gibt in diesem Fall zwei Werte aus (Suche alles, was nicht 0-9 ist und ersetze es durch ein Leerzeichen)

 echo "ksdf:100ajkl:sd50" | sed 's/[^0-9]/ /g'
     100       50

Wenn man die Ausgabe in einer for-Schleife verarbeitet, setzt er in jeden Durchlauf das ein, was angegeben ist in diesem Fall 50 und 100 für einer Variable "i". Die Leerzeichen interessieren bash (in diesem Fall) aber nicht. (Leerzeichen bedeutet Trennzeichen)

Durchlauf 1:

  • c ist noch nicht gesetzt. also nichts + 1 = 1 (c=1)

  • i ist im ersten Durchlauf 100

  • echo $i gibt 100 aus und leitet die Ausgabe um (>) in die Datei file1.txt, c ist ja aktuell 1

Durchlauf 2

  • c ist 1 und wir um 1 erhöht 1 + 1 = 2 (c=2)

  • i ist in diesem Durchlauf 50

  • echo $i gibt 50 aus und leitet die Ausgabe um (>) in die Datei file2.txt, c ist ja aktuell 2

Wenn Du alles in einer Datei haben willt, könntest Du das so lösen:

1
2
3
for i in $(sed 's/[^0-9]/ /g' <inputfile>); do
    echo $i >> file.txt
done

Statt immer einen neuen Dateinamen zu verwenden (c hochzuzählen) wird es mit zwei ">>" an eine Datei angehangen. In diesem Fall ist die Schleife aber hinfällig, Du kannst ja direkt in die Datei schreiben.

 echo "ksdf:100ajkl:sd50" | sed 's/[^0-9]/ /g' > xyz.txt

Ich hoffe das war einigermaßen verständlich 🙄

Grüße und schönen Abend

ka111

(Themenstarter)

Anmeldungsdatum:
22. Juni 2014

Beiträge: 141

Aha ok. Danke für die ausfühliche Erklärung.

Aber wieso ist im 1. Durchlauf i nur 100 und nicht 100 50? Sed gibt ja 100 50 aus.

g00d.morning

Anmeldungsdatum:
20. Februar 2013

Beiträge: 330

Weil bash das Leerzeichen als Trenner versteht, das habe ich aber bereits geschrieben. Was als Trenner verwendet wird, steht in der Systemvariable IFS. Ist per default jegliche Form von whitespace (space, tab, newline).

Wenn Du zum Spaß mal den IFS auf nichts setzt:

IFS=""

wird das Leerzeichen nicht als Trenner erkannt. Alles weitere musst Du Dir aber einfach schlicht anlesen. 😉

ka111

(Themenstarter)

Anmeldungsdatum:
22. Juni 2014

Beiträge: 141

Achso, das ist nicht wie in einer Endlosschleife und fängt von vorne an, sondern es macht sozusagen 1 Aufgabe in mehreren Runden bis das Ziel erfüllt ist, eher wie in einer while schliefe die bis zu einer Bedingung läuft. Und die ganze erste Zeile ist der Satzt indem beschrieben wird wie lange die while-ähnliche Schleife läuft, eigentlich genau so wie du es geschrieben hast 😀 sed wird eigentlich gar nicht ausgeführt sozusagen, sonder ist in der while-ähnlichen Schleife mit eingebaut (und wird da einmal gebraucht).

Ist aber dann doch trotzdem irgendwie komisch dass die Reihenfolge dieser while-ähnlichen Schleife:

c=$((c+1))
1. Zahl
c=$((c+1))
2. Zahl

ist und nicht:

c=$((c+1))
1. Zahl (erster Befehl)
2. Zahl (zweiter Befehl, wegen dem Trennstrich)

Ausser es kommt an den Punkt: echo $i > file$c.txt, und "denkt sich", gut das war die 1. Datei mit Zahl, jetzt machen wir die 2., dafür muss ich den while-ähnliche Befehl nochmal ausführen für die 2., also nochmal von vorne mit dem Befehl, und landet wieder bei c=$[1]. Wenn das so wäre ist es aber irgendwie unverständlicher wieso die Reihenfolge so gemacht wird und nicht 1. Zahl (Befehl 1) 2. Zahl (Befehl 2). Aber ist egal, es ist halt so, wegen dem Trennstrich und dem for do

Guten Abend

  • 1: c+1

g00d.morning

Anmeldungsdatum:
20. Februar 2013

Beiträge: 330

Du denkst zu kompliziert 😈

Du: Hey, bash!
Bash: Ja?
Du: Ich habe eine Aufgabe for Dich
Bash: Ok. Was denn?
Du: sed gibt Dir gleich ein paar Werte, Moment.
sed: Ich, hab was, ich hab was.
bash: Watt denn?
sed: nix, nix, nix, 100, nix, nix, nix, 50
bash: Aha. Ich guck mal eben in meinen IFS rein, was "nix" bedeutet... aha. Das ist ein Trennzeichen. Also die Werte 100 und 50. Was soll ich damit machen?
Du: Setz sie bitte in "i" ein.
bash: OK.
Du: Ach so, wenn du gerade dabei bist...
bash (genervt): Ja?
Du: Wenn Du 100 und 50 für i einsetzt, könntest du direkt jedes mal die Varaible "c" hochzählen?
bash: OK. Noch was?
Du: Ja, gib mir bitte jedes mal, wenn Du 100 und 50 für i eigestetzt hast "i" aus, OK?
bash: Also schön, noch was?
Du: Nur noch eines. Wenn du i ausgibst, gib es nicht mir, sondern leite es um, in die Datei 'file -Variable "c" - .txt'
bash: OK. done

D630

Avatar von D630

Anmeldungsdatum:
24. Juli 2013

Beiträge: 329

g00d.morning schrieb:

Du denkst zu kompliziert 😈

Du: Hey, bash!
Bash: Ja?
Du: Ich habe eine Aufgabe for Dich
Bash: Ok. Was denn?
Du: sed gibt Dir gleich ein paar Werte, Moment.
sed: Ich, hab was, ich hab was.
bash: Watt denn?
sed: nix, nix, nix, 100, nix, nix, nix, 50
bash: Aha. Ich guck mal eben in meinen IFS rein, was "nix" bedeutet... aha. Das ist ein Trennzeichen. Also die Werte 100 und 50. Was soll ich damit machen?
Du: Setz sie bitte in "i" ein.
bash: OK.
Du: Ach so, wenn du gerade dabei bist...
bash (genervt): Ja?
Du: Wenn Du 100 und 50 für i einsetzt, könntest du direkt jedes mal die Varaible "c" hochzählen?
bash: OK. Noch was?
Du: Ja, gib mir bitte jedes mal, wenn Du 100 und 50 für i eigestetzt hast "i" aus, OK?
bash: Also schön, noch was?
Du: Nur noch eines. Wenn du i ausgibst, gib es nicht mir, sondern leite es um, an die Datei 'file -Variable "c" - .txt'
bash: OK. done

weltklasse! 😀

ka111

(Themenstarter)

Anmeldungsdatum:
22. Juni 2014

Beiträge: 141

hahaha 😀

Ja irgendwie muss man sich das ja vorstellen 😀

Antworten |