www.mikrocontroller.net

Forum: PC-Programmierung Zeilenumbruch in Textdatei entfernen, wie am besten?


Autor: Msp 430_crew (msp430_crew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich möchte am besten per Batch oder RegExp alle Umbrüche + 2 Leerzeichen 
nach 80 Zeichen löschen.

Beispiel:
m-description: Index attribute for DN whose values are NOT normalized in any
  way

Wie kann ich das am besten lösen?

Viele Grüße,
msp430_crew

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit awk lässt sich sowas bestimmt hinfummeln, wenn man vorher nicht an 
awk verzweifelt.

Abgesehen davon hat deine erste Beispielzeile keine 80 Zeichen.
Müssen es genau 80 sein, damit das LF entfernt wird?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Mit awk lässt sich sowas bestimmt hinfummeln, wenn man vorher nicht an
> awk verzweifelt.

Geht garantiert.
Sowohl die Aufgabenstellung als auch das Verzweifeln :-)

Ich bevorzuge ganz ehrlich in solchen Fällen einen C-Compiler (zu meiner 
Schande). Noch ehe ich mir in AWK (oder SED) das was ich brauche 
zusammengesucht habe, läuft das C-Programm schon längst.

Kannst du mit einem Hammer umgehen, ist jedes Problem im Prinzip nur 
noch ein Nagel.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ich bevorzuge ganz ehrlich in solchen Fällen einen C-Compiler (zu meiner
> Schande). Noch ehe ich mir in AWK (oder SED) das was ich brauche
> zusammengesucht habe, läuft das C-Programm schon längst.

Würde ich auch, aber den meisten Hilfesuchenden ist das eher
keine gute Empfelhung.
Wäre es für sie ein guter Weg, würden sie nicht fragen sondern
selbst drauf kommen.

Karl heinz Buchegger schrieb:
> Kannst du mit einem Hammer umgehen, ist jedes Problem im Prinzip nur
> noch ein Nagel.

Nun ist C ein recht vielseitiger Hammer, wozu also das schlechte
Gewissen? (Höchstens, weil man nicht C++ genommen hat.)

Autor: Hrm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Kannst du mit einem Hammer umgehen, ist jedes Problem im Prinzip nur
> noch ein Nagel.

Achso. Dann war das garnicht mein Daumen, sondern mein Problem das mir 
neulich so weh getan hat. <:-)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
awk --posix '/^.{80,}/ { printf $0; remove_spaces=1; next} remove_spaces==1 {sub(/^  /,""); print; remove_spaces = 0;} {print}'

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ruby -e 'puts STDIN.read.gsub(/^(.{70,})\r?\n  /, "\\1 ")'

Ob ruby, perl oder awk, irgend ein Werkzeug zur Textverarbeitung sollte 
man schon haben, das mit C zu machen ist jedenfalls alles andere als 
effizient.

Autor: Msp 430_crew (msp430_crew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für Eure Hilfe. Ich finde Ruby sehr interessant, würde mich 
gerne damit beschäftigen. Wie kann ich eine einlesen, verarbeiten und 
dann wieder zurückschreiben?
Mein Ansatz wäre folgender, der aber nicht funktioniert...ich 
überschreibe nur die ldif...:-(
datei=File.open("schema.ldif", "r")
text = datei.gets
datei.close

datei=File.open("schema.ldif","w")
datei.puts STDIN.read.gsub(/^(.{80,})\r?\n  /, "\\1 ")
datei.close

Danke schon mal :-)

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, kein Wunder, du erstellst zwar eine Variable "text", aber 
verwendest sie nicht (und außerdem liest gets nur eine Zeile).

Probier's mal so:
text = File.read("schema.ldif") # (Abkürzung für open, read, close)

datei = File.open("schema.ldif", "w")
datei.write(text.gsub(/^(.{80,})\r?\n  /, "\\1 "))
datei.close

Oder Ruby-mäßiger ausgedrückt:
text = File.read("schema.ldif") # (Abkürzung für open, read, close)

File.open("schema.ldif", "w") do |datei|
  datei.write(text.gsub(/^(.{80,})\r?\n  /, "\\1 "))
end

(damit wir die Datei am Ende des Blocks automatisch geschlossen)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Karl heinz Buchegger schrieb:
>> Kannst du mit einem Hammer umgehen, ist jedes Problem im Prinzip nur
>> noch ein Nagel.
>
> Nun ist C ein recht vielseitiger Hammer, wozu also das schlechte
> Gewissen? (Höchstens, weil man nicht C++ genommen hat.)

Naja, Stringverarbeitung ist nicht gerade eine Stärke von C, um es mal 
vorsichtig auszudrücken, und Skriptsparachen wie awk (oder python, ruby, 
perl, php, ...) sind genau für sowas gemacht.
Und um mich auch an den Analogien zu beteiligen: Man bekommt auch mit 
einem Hammer eine Schraube in die Wand, aber mit einem Schraubenzieher 
geht's trotzdem besser.

Autor: Msp 430_crew (msp430_crew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe noch eine Verständnisfrage :-) :
 datei.write(text.gsub(/^(.{80,})\r?\n  /, "\\1 "))

Bedeutet so viel, dass ich den Inhalt von text einlese in einen String 
und bei jedem auftreten von \r?\n nach mindestens 80 Zeichen genau 
diesen Part austausche durch nichts? Was ist \\1? Steht das für den Part 
/..../ als 1 Variable?

VG

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für den Teil der Eingabe, der auf den ersten (und in diesem
Fall einzigen) mit () geklammerten Teilausdruck des Suchmusters
passt. Also die 80 Zeichen, die zu . passen.

\2 wäre entsprechend ein zweiter geklammerter Teilausdruck etc.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Msp 430_crew schrieb:
> Ich habe noch eine Verständnisfrage :-) :
>
>  datei.write(text.gsub()
>
>
> Bedeutet so viel, dass ich den Inhalt von text einlese in einen String
> und bei jedem auftreten von \r?\n nach mindestens 80 Zeichen genau
> diesen Part austausche durch nichts?

Vom Ergebnis her ja, aber genau genommen bedeutet es, daß du diesen Part 
zusammen mit den 80 Zeichen davor ersetzt durch nur die 80 Zeichen 
davor.

Autor: Ing. ET (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wäre es für sie ein guter Weg, würden sie nicht fragen sondern
> selbst drauf kommen.

Das stimmt bei mir nicht.
Ich bin oft von anderen, auch in diesem Forum, auf super Loesung 
gestossen worden, wo theoretisch von alleine draufkommen haette koennen.
Vielleicht geht es manch anderen auch so.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na gut, du hast es so gewollt:

KHB hat Recht (selten, aber schon wieder). Bevor man mühsam
einen regulären Ausdruck hinfummelt, der in einer Zeile viel
Unverständliches enthält und vielleicht das macht, was man will,
habe ich schneller ein C++-Programm mit vielleicht 10 Zeilen
geschrieben, das ich auch verstehe und bei Bedarf wesentlich
flexibler ist, wenn es doch komplizierter wird.

Je nach dem, wo man halt mehr Übung hat.

Die RE-Lösung ist nicht unbedingt schlechter, aber für mich
wäre sie fehlerträchtiger.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
na gut, etwas mehr als 10 Zeilen:
#include <iostream>
#include <fstream>
#include <string>


int main( int nargs, char **args )
{
  std::ifstream    datei( "t.txt" );
  std::ostream    &ausgabe = std::cout;
  // oder gleich in Datei: std::ofstream    ausgabe( "ausgabe.txt" );
  std::string      zeile;
  size_t           letzteZeilenlaenge = 0;
  size_t           zeilennummer       = 0;

  while( std::getline( datei, zeile ) )
  {
    if( ++zeilennummer==1 ) // erste Zeile immer ausgeben:
    {
      ausgabe << zeile;
    }
    else if( letzteZeilenlaenge>0
             &&
             zeile.size()>2
             &&
             zeile[0]==' '
             &&
             zeile[1]==' '
             )
    {
      // ab 2. Zeile Ausgabe mit einem Leerzeichen vorweg, aber kein
      // Zeilenvorschub, wenn es eine Folgezeile ist:
      ausgabe << zeile.substr( 1 );
    }
    else
    {
      // ansonsten vorhergehende Zeile mit LF beenden und die aktuelle
      // normal ausgeben:
      ausgabe << std::endl << zeile;
    }

    letzteZeilenlaenge = zeile.size();
  }

  ausgabe << std::endl; // letzte Zeile terminieren
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Anfangszeile immer genau 80 Zeichen haben soll, um die
nächste anzuhängen, ist die Bedingung im else if... entsprechend
zu ändern.

(In deinem Beispiel sind es weniger als 80 Zeichen)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Na gut, du hast es so gewollt:
>
> KHB hat Recht (selten, aber schon wieder).

Ui, da hab ich wieder was losgetreten :-)

Ich wollte doch eigentlich den TO dazu nötigen, mal ein Wort darüber zu 
verlieren, was er denn eigentlich von sich aus machen kann, bzw. ihm Mut 
machen, das Problem mit den Mitteln die er schon kennt anzugehen.


> habe ich schneller ein C++-Programm mit vielleicht 10 Zeilen
> geschrieben, das ich auch verstehe und bei Bedarf wesentlich
> flexibler ist, wenn es doch komplizierter wird.

Geht mir auch so.
(Ralf. Das C nicht zu ernst nehmen. Ob C oder C++ ist nicht so wichtig. 
In meiner C-Lernzeit hab ich gemerkt, dass


int main()
{
  int c;

  while( ( c == getchar() ) !== EOF ) {
    ...
  }
}

ein ziemlich flexibler Ansatz ist. Mit ein paar Modifikationen im ... 
Teil kann man damit recht schnell Textfilter bauen. Nach Bedarf diverse 
Zähler oder Flags dazu und man hat ziemlich flott etwas brauchbares. 
Natürlich nur, wenn man C schon kann.

Ich kann nun mal mit den Regular-Expression Sprachen nicht viel anfangen 
und für mich führt das schneller zu einer brauchbaren Lösung.

Aber ich geb zu, ich hab die Aufgabenstellung nicht wirklich verstanden. 
Wie, was, 80 Zeichen, Umbrüche?

Was soll das Ziel sein?
Eine Textzeile, die auf irgendwelchen dubiosen Wegen auf mehrere 
aufgeteilt wurde, wieder zu einer einzigen zu vereinen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.