• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Zeilenumbruch entfernen aus Datei

RedRaptor

Newbie
Hallo Leute,
ich bräuchte euere hilfe.

ich habe eine Textdatei mit folgendem inhalt:

Code:
text bla bla bla text bla bla   ;
text lblublblblblubbb "" '' abcdef09871 ;
text blubbl {
}

ich möchte das alle Zeilen die einen ";" am Ende haben keinen Zeilenumbruch haben. An sich eine einfache Aufgabe für sed:
Code:
sed -r -e 's/\s*;\s*\r//g' Inputfile > Outputfile
(ja es sind Windows Zeilenunbrüche ... -.-. Allerdings aussschließlich, also kein Mischmasch - mal so mal so - sondern immer. )
Da reguläre ausdrücke nerfig zu lesen sind hier eine Kurzerklärung:
egal wieviel Whitespaces (Tab, Leerzeichen etc) gefolgt von einem ";" gefolgt von egal wieviel whitespaces, gefolgt von einem Zeilenumbruch (Windows)
ersetzen mit ==> nichts
Funktioniert leider nicht ganz. Die regular expression trifft zwar, aber er ersetzt jedes einzelne "Element" darin.
Für ich beispielsweise eine ersetzung anstelle von nichts mit "test" aus sieht der Output so aus:
Code:
text bla bla bla text bla bla testtesttest
text lblublblblblubbb "" '' abcdef09871testtest
text blubbl {
}
er trifft aber er ersetzt vollkommen Falsch. Mal abgesehen davon das die Zeilenumbrüche immernoch vorhanden sind.


Gleiches Spiel mit awk:
Code:
awk '{ sub(/\s*;\s*\r$/,""); print $0 }' Inputfile  > Outputfile
Er trifft, ersetzt auch soweit richtig (sprich die ganzen whitespaces und ";" fallen weg), aber der Zeilenumbruch bleibt.....

Wo genau liegt der Wurm?
 

RME

Advanced Hacker
Hallo,

sed arbeitet nur zeilenweise; der Zeilenumbruch am Ende kann nicht editiert werden.

Um dies trotzdem zu ermöglichen musst Du zwei Zeilen aufs mal einlesen -- mit der 'N' (append next line) Option. Der Befehl ist dann aber mehrzeilig.

Einfacher:

Code:
tr -d "\015" < input.txt > output.txt
\015 = CR, \012 = LF

Gruss,
Roland
 

abgdf

Guru
Könnte sein, daß ein Perleinzeiler alles in eine Zeile liest:
Code:
perl -pe 's/\s*;\n//g' Inputfile
Bin nicht sicher. Ausgeschrieben als Skript sähe das so aus:
Code:
#!/usr/bin/perl

use warnings;
use strict;

open(FH, "<$1");
local $/;
$_ = <FH>;
close(FH);
local ($/) = "\n";
s/\015?\012/\n/g;
s/\s*;\n//g;
print;
Wäre als
Code:
./perlskript.pl Inputfile
aufzurufen. Die Zeile mit 015... wandelt Windows/DOS-Format in das Unix-Format, also wie der Befehl "unix2dos" (den man sonst auch einsetzen könnte).
 
OP
R

RedRaptor

Newbie
Danke für die Antworten.

RME schrieb:
Hallo,

sed arbeitet nur zeilenweise; der Zeilenumbruch am Ende kann nicht editiert werden.

Um dies trotzdem zu ermöglichen musst Du zwei Zeilen aufs mal einlesen -- mit der 'N' (append next line) Option. Der Befehl ist dann aber mehrzeilig.

Einfacher:

Code:
tr -d "\015" < input.txt > output.txt
\015 = CR, \012 = LF

Gruss,
Roland
"tr" ist natürliche die einfachste Methode, allerding benötige regular expressions....Denn er soll nur dann etwas tun wenn BEDINGUNG XY erfüllt ist, im spezifischen Falle oben wäre das an jeder Zeile mit ";" am Schluss. Aufgrund dessen fällt "tr" aus. Mein erster Gedanke war - klar sed und gut. Aber der kann wieder keine richtigen regex. Nur ssed kanns die komplexeren und das steht leider nicht zur Verfügung (das mit dem ; und den Leerzeichen ist vom regex nur ein Beispiel. da stehen noch viel Komplexere Dinge an....).
was ist mit awk? Ich denke mal aus dem gleichen Problem wie bei sed. gibts hier einen Workaround?

abgdf schrieb:
Könnte sein, daß ein Perleinzeiler alles in eine Zeile liest:
Code:
perl -pe 's/\s*;\n//g' Inputfile
Bin nicht sicher. Ausgeschrieben als Skript sähe das so aus:
Code:
#!/usr/bin/perl

use warnings;
use strict;

open(FH, "<$1");
local $/;
$_ = <FH>;
close(FH);
local ($/) = "\n";
s/\015?\012/\n/g;
s/\s*;\n//g;
print;
Wäre als
Code:
./perlskript.pl Inputfile
aufzurufen. Die Zeile mit 015... wandelt Windows/DOS-Format in das Unix-Format, also wie der Befehl "unix2dos" (den man sonst auch einsetzen könnte).

Ja mit Perl hätte ich mit den REGEX wohl die wenigsten Probleme, aber da ich des PERLs nicht mächtig bin, dürfte diese Lösung für mich recht unpassend sein.
 

abgdf

Guru
Argh, Fehler oben im Perl-Skript. Der Vollständigkeit halber nochmal:
Code:
#!/usr/bin/perl
use warnings;
use strict;
open(FH, "<$ARGV[0]") or die;
local $/;
$_ = <FH>;
close(FH);
local ($/) = "\n";
s/\015?\012/\n/g;
s/\s*;\n//g;
print;
Auch nochmal etwas ausführlicher und verständlicher:
Code:
#!/usr/bin/perl

use warnings;
use strict;

# Textdatei in eine Liste namens @a einlesen:
open(FH, "<$ARGV[0]") or die;
my @a = <FH>;
close(FH);

# Von jeder Zeile der Liste das Zeilenende entfernen:
chomp(@a);

# Die Liste zu einem einzigen String zusammenfügen:
my $b = join("\n", @a);

# Mit regulärem Ausdruck Zeichen löschen:
$b =~ s/\s*;\n//g;

# Ergebnis ausgeben:
print $b;
Wie gesagt, starten mit "./perlskript.pl test.txt".
Vielleicht kannst Du das so ja doch schon verstehen, immerhin kennst Du schon reguläre Ausdrücke, das ist ja schon die halbe Miete. Weitere Hilfe gäbe es auch im Perl-Forum. Dort gibt es auch gerade so ein ähnliches Thema.
 
Oben