# [Perl]: Anfängerfrage



## GilbertGrape (26. Aug 2008)

Hallo,

ich habe angefangen, mich ein wenig mit Perl zu beschäftigen, weil es wohl für Textbearbeitung geeignet sein soll.
Ich habe jetzt mein erstes Progrämmchen geschrieben, das folgendes tun soll.
Ich habe eine Datei, in der steht am Anfang jeder Zeile eine Zahl und dann folgt ein Leerzeichen. Ich möchte jetzt anstelle des Leerzeichens ein Tab haben.
Mein Programm dazu sieht so aus:


```
use strict;

open(LESEN,"u:/Eigene Dateien/myWorkspace/Perl-tools/test.txt")
  or die "Fehler beim Öffnen von 'test.txt': $!\n";
open(SCHREIBEN,"> neu.txt")
  or die "Fehler beim Öffnen von 'neu.txt': $!\n";

while(defined(my $i = <LESEN>)) {
	if ($i =~ /[\d]{0,3} /)  {
		my $found = $&;       
		$found =~ s/ /\t/;      //hier ersetze ich in dem gefundenen Ausdruck das Leerzeichen durch ein Tab
		$i =~ s/$&/$found/;   //hier ersetze ich dann den gefundenen Ausdruck durch den eben veränderten
		print SCHREIBEN $i;   //Ausgabe in neue Datei
	}	
}
close(LESEN);
close(SCHREIBEN)
  or die "Fehler beim Schließen von 'neu.dat': $! \n"
```

Das Problem ist jetzt, dass zum Beispiel eine Originalzeile so aussieht:

1 Natalizumab 1 149

und er macht daraus:

11	       Natalizumab 1 149

Das heißt, der Tab wird richtig gesetzt, aber er hat die Zahl am Anfang doppelt.

Kann mir vielleicht jemand sagen, was der Fehler ist?
Oder geht sowas sowieso irgendwie einfacher??

Danke schonmal!


----------



## foobar (26. Aug 2008)

Das geht auch einfacher:


```
#!/usr/bin/perl -w

while(<>)
{
  s/(\d)\s(.*?)/$1\t$2/gsi;
  print;
}
```

Aufruf:
cat in | ./conv_tab.pl > out

Lass das lesen, öffnen, erstellen von Files doch das OS erledigen. Das so üblich unter Unix.


----------



## GilbertGrape (26. Aug 2008)

foobar hat gesagt.:
			
		

> Das geht auch einfacher:
> 
> 
> ```
> ...



Das versteh ich nicht so ganz. In $1 und $2 steht doch jeweils das erste und zweite Ergebnis oder? und dazwischen wird ein Tab gesetzt? So wollte ich das nicht, denn nach dem ersten Leerzeichen kommt nicht zwangsweise wieder eine Zahl.



			
				foobar hat gesagt.:
			
		

> Aufruf:
> cat in | ./conv_tab.pl > out
> 
> Lass das lesen, öffnen, erstellen von Files doch das OS erledigen. Das so üblich unter Unix.


Ich arbeite nicht unter Unix, sondern unter Windows


----------



## foobar (26. Aug 2008)

GilbertGrape hat gesagt.:
			
		

> Das versteh ich nicht so ganz. In $1 und $2 steht doch jeweils das erste und zweite Ergebnis oder? und dazwischen wird ein Tab gesetzt? So wollte ich das nicht, denn nach dem ersten Leerzeichen kommt nicht zwangsweise wieder eine Zahl.



Dann mußt du das Pattern anpassen. Ich kenne ja deine Daten nicht. Zeig mal ein paar mehr Daten, dann finde ich nen passenden Regex dafür.


----------



## GilbertGrape (26. Aug 2008)

Also, am Anfang jeder Zeile kommt eine Zahl (maximal 3-stellig), dann kommt ein Leerzeichen und dann noch einiges, was aber egal ist (also einfach noch mehr Text, Zahlen, Leerzeichen und so) und ich möchte das erste Leerzeichen (also das nach der Zahl) durch einen Tab ersetzen.


----------



## foobar (26. Aug 2008)

Na dann ist der Regex doch OK.


```
s/(\d) (.*?)/$1\t$2/gsi;
```
Wenn es immer genau 1 Blank ist, kannste das auch so schreiben.


----------



## masta // thomas (26. Aug 2008)

```
s/^(\d+) (.*?)$/$1\t$2/gsi
```


----------



## foobar (26. Aug 2008)

Ansonsten findest du hier bestimmt mehr Hilfe: http://www.perl-community.de/


----------



## GilbertGrape (27. Aug 2008)

aber in $2 steht doch das 2. Vorkommen oder?
Das heißt: wieder eine Zahl mit einem Leerzeichen dahinter oder?
Das heißt, er macht den Tab dann zwischen 2 Zahlen.
Die Zeile kann aber so aussehen:

11 blabla fneofni efpj

In diesem Fall gibts doch kein 2. Vorkommen, weil blabla ja keine Zahl ist.
Oder versteh ich das falsch?


----------



## foobar (27. Aug 2008)

In $2 steht das Ergebnis der 2. Capturegroup in dem Fall (.*?) d.h. beliebige Zeichen nicht gierig. In der 1. Capturegroup (\d+) stehen beliebig viele Zahlen. Auf dein Beispiel würde mein Regex genauso matchen.


----------



## GilbertGrape (27. Aug 2008)

Oh man, vielen Dank!
Sorry, dass ich mich ein bißchen glatt angestellt habe, aber das is irgendwie alles so ganz anders als java 

Gruß!


----------



## foobar (27. Aug 2008)

GilbertGrape hat gesagt.:
			
		

> aber das is irgendwie alles so ganz anders als java



hehe, gut erkannt ;-)

Wenn du wirklich Perl lernen willst, mußt du die Bibel lesen.

Perl macht wirklich Spaß, weil man viel Probleme mit nur wenigen Zeilen Code lösen kann. Sowas vermisse ich in Java auch oft. Besonders wenn es um Stringverarbeitung geht.


----------

