UNIX Problem
lima-city → Forum → Programmiersprachen → Sonstige Programmiersprachen
aktuelle zeile
aufruf
code
datei
einzelnen befehle
erledigen
file
gesetzt code
http
kleiner hinweis
komplette datei
label
lauf
mitteln
problem
programm
schenken
speichern
url
zeile
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hallo
Nicht getestet:
tr -d '\n\r' < yourfile.txt xargs -n3 < file
Alle Zeilenumbrüche entfernen und dann alle 3 Wörter einen Zeilenumbruch machen.
https://stackoverflow.com/questions/3134791/how-do-i-remove-newlines-from-a-text-file
https://stackoverflow.com/questions/15979802/how-to-insert-a-newline-n-after-x-numbers-of-words-with-awk-or-sed
mfg
Beitrag zuletzt geändert: 9.10.2014 14:32:53 von voloya -
Hey,
danke für die schnelle Reaktion! Habe gerade einmal ausprobiert. Der Ansatz gefällt mir, allerdings habe ich nach dem 1. Schritt nur noch eine einzige Zeile:
NachnameAVornameAAlterANachnameBVornameBAlterB
Das ist dann quasi ein Wort und kann folglich nicht mehr getrennt werden. Hast du vielleicht eine Idee wie ich nach dem 1. Schritt Leerzeichen zwischen die 'Wörter' kriege? :D
Trotzdem schonmal / nochmal danke
LG -
Hallo,
awk kann auch mit mehreren Zeilen umgehen. Auf dieser Seite gibt es dazu unter anderem ein Beispiel:
https://www.gnu.org/software/gawk/manual/html_node/Multiple-Line.html
Die Beispieldaten der Seite:
Jane Doe 123 Main Street Anywhere, SE 12345-6789 John Smith 456 Tree-lined Avenue Smallville, MW 98765-4321 …
Und das awk-Skript:
# addrs.awk --- simple mailing list program # Records are separated by blank lines. # Each line is one field. BEGIN { RS = "" ; FS = "\n" } { print "Name is:", $1 print "Address is:", $2 print "City and State are:", $3 print "" }
Damit sollte das kein Problem sein. -
Hallo
buyworld schrieb:
allerdings habe ich nach dem 1. Schritt nur noch eine einzige Zeile:
NachnameAVornameAAlterANachnameBVornameBAlterB
Das ist dann quasi ein Wort und kann folglich nicht mehr getrennt werden. Hast du vielleicht eine Idee wie ich nach dem 1. Schritt Leerzeichen zwischen die 'Wörter' kriege? :DLG
Ich wusste doch, dass ich etwas vergessen hatte.
Vielleicht als ersten Schritt:
sed -e 's/^/ /' dateialt.txt > dateineu.txt
.. um ein Leerzeichen vor jede Zeile zu setzen.
Habe momentan keinen Zugriff auf Linux, kann es also nicht ausprobieren.. Danach müssten dann die Leerzeichen am Zeilenanfang wieder entfernt werden.
mfg -
Hi,
das kannst du auch komplett mit sed machen, dann sähe das in etwa so aus;
sed -e ':a;N;$!ba;s/\(.\)\n/\1 /g' file.txt > newFile.txt
Zur Erklärung:
sed ist ein Programm welches eine Datei Zeilenweise verarbeitet und dabei z.B. reguläre Ausdrücke zum suchen und ersetzten anwendet um die Ausgabe zu verändern. Die einzelnen Befehle werden durch Semikolon getrennt.
erstellt ein label, in dem die aktuelle Zeile gespeichert wird.:a
sorgt dafür, dass die aktuelle Zeile und die nächste Zeile eingelesen wird. Dabei werden die Zeilen durch ein \n zusammen gesetzt.N
sorgt dafür, dass die statt der aktuellen Zeile mit dem label vom Anfang gearbeitet wird, hierbei muss beachtet werden, dass dadurch im laufe des Programms die komplette Datei im Arbeitspeicher landet und das Programm immer langsamer wird. Dieser Aufruf sollte also nicht bei zu großen Dateien angewendet werden. Ich würde aber sagen bis ca 1 oder 2 MB besteht kein Problem.$!ba
ist der reguläre Ausdruck der dafür sorgt, dass die Datei wie gewünscht formatiert wird. Er ersetzt den Zeilenumbruch hinter einem Wort durch ein Leerzeichen, aber nur wenn in der Zeile etwas steht.s/\(.\)\n/\1 /g
Auch in awk ist das Ganze nicht so wahnsinnig schwer, hier ist das Programm zwar länger, hat dafür aber nicht mehr die Probleme mit dem Speicher.
awk 'function a(c){print substr(c,0,length(c))};BEGIN{b=""};{if($1==""){a(b);b=""}else{b=b$1" "}};END{a(b)}' file.txt > newFile.txt
Ich habe das Programm hier einmal eingekürzt, schlauerweise speichert man es aber in einer Datei, z.B. reformatFile.awk und ruft das Programm dann so auf:awk -f reformatFile.awk file.txt
In der Datei kann man das Programm dann auch besser strukturieren:function printTrimmed(outputLine){ print substr(outputLine, 0, length(outputLine)) } BEGIN{ tmpOutputLine="" } { if($1==""){ printTrimmed(tmpOutputLine) tmpOutputLine="" }else{ tmpOutputLine=tmpOutputLine$1" " } } END{ printTrimmed(tmpOutputLine) }
Und zu guter Letzt möchte ich noch meinen persöhlichen Favoriten zeigen, nämlich perl. Perl ist eigentlich immer installiert, zumindest kenne ich keine Unix-Systeme mehr, die es nicht haben und es hat nicht die erwähnten Probleme, wie z.B. sed und ist andererseits sehr mächtig. Außerdem ist perl erheblich schneller als die anderen beiden Alternativen . Da sähe das Programm dem aus awk sehr ähnlich:
perl -e '$a="";sub a{chomp $a;print $a."\n";$a=""}while(<>){chomp;$a.=$_." ";if($_ eq ""){a()}}a()' < file.txt > newFile.txt
Oder um das Programm wieder übersichtlich darzustellen als file, welches so genutzt wird:
und so aussähe:perl reformatFile.pl < file.txt > newFile.txt
use strict; use warnings; my $tmpLine=""; while(<>){ chomp; $tmpLine.=$_." "; if($_ eq ""){ printTrimmed(); } } printTrimmed(); sub printTrimmed { chomp $tmpLine; print $tmpLine . "\n"; $tmpLine = ""; }
Wie du siehst gibt es da diverse Lösungen, die alle mit Unixboardmitteln zu erledigen sind.
Ein kleiner Hinweis sei allerdings nocht gestattet, denn die Lösungen funktionieren, nicht alle gleich (außer die Perl-Variante). Die sed Variante funktioniert nur mit der GNU-Variante von sed, allerdings kann man das Problem beseitigen, indem man ähnlich wie in der awk-, oder perl-Variante das Programm in eine Datei schreibt. Ansonsten sollten die Programme aber alle laufen.
Mit freundlichen Grüßen
* Edit Hinweis zu GNU hinzugefügt
Beitrag zuletzt geändert: 11.10.2014 15:33:07 von nemoinho -
nemoinho schrieb:
Auch in awk ist das Ganze nicht so wahnsinnig schwer, hier ist das Programm zwar länger, hat dafür aber nicht mehr die Probleme mit dem Speicher.
awk 'function a(c){print substr(c,0,length(c))};BEGIN{b=""};{if($1==""){a(b);b=""}else{b=b$1" "}};END{a(b)}' file.txt > newFile.txt
Ich habe das Programm hier einmal eingekürzt, schlauerweise speichert man es aber in einer Datei, z.B. reformatFile.awk und ruft das Programm dann so auf:awk -f reformatFile.awk file.txt
In der Datei kann man das Programm dann auch besser strukturieren:function printTrimmed(outputLine){ print substr(outputLine, 0, length(outputLine)) } BEGIN{ tmpOutputLine="" } { if($1==""){ printTrimmed(tmpOutputLine) tmpOutputLine="" }else{ tmpOutputLine=tmpOutputLine$1" " } } END{ printTrimmed(tmpOutputLine) }
Mit dem von mir oben verlinkten Beispiel schenken sich perl und awk zeitlich gesehen nix
Und es schaut auch noch besser aus
Hier ist das ganze mit dem RS von awk auch nochmal erläutert:
http://www.thegeekstuff.com/2010/01/8-powerful-awk-built-in-variables-fs-ofs-rs-ors-nr-nf-filename-fnr/ -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage