Problem mit sed (newline am Ende)

V

Viperb0y

Jungspund
Hallo,

ich habe ein Problem mit sed:

Ich verwende folgendes Script:
Code:
sed -n '/^[^#|^ ].*/p' /k/_builder/versions.conf > /k/_builder/versions.conf.tmp

um kommentare und leerzeilen aus einer Konfigurationsdatei zu löschen. Allerdings hängt mir sed am Ende der geschriebenen Datei wieder eine leerzeile an. Kann man das ausschalten? Weil genau diese leerzeile stört mich :(.

Geht das überhaupt? Ich hoffe mal :(
 
Ich denke, dass sed keine Zeile einfügt, sondern einfach durch eine leere Zeile ersetzt. Nutze anstelle des Substitutionskommandos 'p' das Zeilenlöschkomando 'd'.
 
Hallo,

hm, er fügt doch keine leere Zeile an. In der Quelldatei war noch eine leer Zeile am Ende der Datei, mein Fehler.

Aber gibts eine möglichkeit auch die leere Zeile am ende der Datei zu löschen? Weil aktuell löscht er ja leer zeilen, nur nicht die am Ende o.O

Hier nochmal der Befehlscode:
Code:
sed -n '/^[^#|^\n].*/p' /k/_builder/versions.conf > /k/_builder/versions.conf.tmp

Das Ursprungsfile:
Code:
# Testkommentar
0 netcologne rel-3-1-26-0 3030 3031 3032

0 emds rel-3-1-26-0 3033 3034 3035
0 emds rel-3-1-25-0 4000 4001 4002

Das Endfile:
Code:
0 netcologne rel-3-1-26-0 3030 3031 3032
0 emds rel-3-1-26-0 3033 3034 3035
0 emds rel-3-1-25-0 4000 4001 4002
0 infodesire curr 4003 4004 400

:-/ Der will mir die letzte Zeile nicht löschen :(

EDIT: P.S. Ich komme auch aus Mainz ;)
 
Zuletzt bearbeitet:
Gefühlsmäsßig würde ich das so machen (hab's aber nicht getestet)
Code:
sed -n '/^[#|\n| ]/d' ...
Im Moment weiß ich noch nicht, warum du zweimal ein ^ verwendest.
 
Hallo,

Code:
sed -n '/^[#|\n| ]/d' /k/_builder/versions.conf > /k/_builder/versions.conf.tmp

Ergibt garnichts :) Einfach ne leere Datei :)

Das ^ verwende ich dafür damit nur die zeilen mit mit \n oder # anfangen beachtet werden, da ja jede zeile am ende ein \n hat ;) Ohne gehts nicht :)

EDIT:
Code:
sed '/^[#|\n| ]/d' /k/_builder/versions.conf > /k/_builder/versions.conf.tmp

Ergibt folgende ausgabe:

Code:
0 netcologne rel-3-1-26-0 3030 3031 3032

0 emds rel-3-1-26-0 3033 3034 3035
0 emds rel-3-1-25-0 4000 4001 4002
 
Zuletzt bearbeitet:
Hallo
Versuchs mal damit:
Code:
sed '/^[#|\n]/d;/^$/d' /file/foo > /file/bar
Gruss
d22
 
Hallo

Deine Leerzeile wird deshalb ausgegeben, weil sie auf deine Regexp matcht.
Eine von vielen Lösungen für GNU sed:
Code:
wolle@Nietzsche:~/temp
$ cat testdatei
 foo bar
 foo bar baz
 #comment
 # more comment
 vorletzte Zeile


wolle@Nietzsche:~/temp
$ sed -ne '/^[^#]*$/{/^$/!p}' testdatei
 foo bar
 foo bar baz
 vorletzte Zeile
wolle@Nietzsche:~/temp

Gruß Wolfgang
 
Das ^ verwende ich dafür damit nur die zeilen mit mit \n oder # anfangen beachtet werden, da ja jede zeile am ende ein \n hat ;) Ohne gehts nicht :)

Natürlich, eben war ich ganz irr.
Jetzt habe ich auch die Dinge mal gestetet. Ist merkwürdig. Auch die Docs, die ich gerade lese, sind hierbei etwas verwirrend.
 
Hallo,

vielen dank erstmal für die viele Hilfe, glaube ich hab das Problem falsch beschrieben, sorry :(:

Wenn ich `cat versions.conf` mache soll statt:
Code:
viper@pylon ~ $ cat versions.conf
0 netcologne rel-3-1-26-0 3030 3031 3032
0 emds rel-3-1-26-0 3033 3034 3035
0 emds rel-3-1-25-0 4000 4001 4002
viper@pylon ~ $

dies:

Code:
viper@pylon ~ $ cat versions.conf
0 netcologne rel-3-1-26-0 3030 3031 3032
0 emds rel-3-1-26-0 3033 3034 3035
0 emds rel-3-1-25-0 4000 4001 4002viper@pylon ~ $

kommen.

Problem ist halt dabei dass auf diese versions.conf Linux und Wintendo Rechner im Netzwerk drauf zugreifen und diese entweder mit oder ohne newline am Ende der Datei speichern. Dies würde ich halt vorher schon filtern. Das mit den # und \n irgendwo in der Datei funktioniert jetzt wunderbar. Nur halt der Rest nicht.

EDIT:

Gerade gelesen im sed faq gelesen:
http://sed.sourceforge.net/grabbag/tutorials/sedfaq.txt
Code:
5.10. Why can't I match or delete a newline using the \n escape sequence?
      Why can't I match 2 or more lines using \n?

   The \n will never match the newline at the end-of-line because the
   newline is always stripped off before the line is placed into the
   pattern space.
Scheint so als ob es garnicht gehen würde, gibts evtl. eine andere Methode dafür?
 
Zuletzt bearbeitet:
Ja, hab gerade folgendes gefunden:
Thus, scripts like
Code:
   sed 's/\n//' file       # to delete newlines from each line
   sed 's/\n/foo\n/' file  # to add a word to the end of each line
will NEVER work, because the trailing newline is removed _before_
the line is put into the pattern space. To perform the above tasks,
use one of these scripts instead:
Code:
   tr -d '\n' < file              # use tr to delete newlines
   sed ':a;N;$!ba;s/\n//g' file   # GNU sed to delete newlines
   sed 's/$/ foo/' file           # add "foo" to end of each line
von: http://www.cs.uu.nl/wais/html/na-dir/editor-faq/sed.html

Gruss
d22
 
Hallo,

ausser mit tr bekomm ich die letzte newline aber nicht weg :( Nur tr löscht mir dann alle newlines :D.

Ich glaub ich verzweifele :hilfe2:

Eigentlich kann es doch garnicht so schwer sein dass diese "obligatorische newline" am ende der datei nicht geschrieben wird :-/.
 
Ich weiss es ist furchtbar umständlich, aber es klappt mal fürs Erste:
Code:
line=$(tail -1 FILE) && sed -i '$d' FILE && echo $line | tr -d '\n' >> FILE
Geht bestimmt auch einfacher....
Bin gespannt was die 'echten Könner' so vorschlagen ;).

Gruss
d22
 
Dumme Frage: handelt es sich um unter MS Windows erstellte Texte?
 
Hallo,

klappt! Dankeschön :) Endlich ist der Nervenkitzel weg :D

EDIT: Teils. Die Datei wird manchmal mit Wintendo bearbeitet und manchmal mit Linux. Jetzt klappt es aber
 
Zuletzt bearbeitet:
Hallo
Mit sed alleine fällt mir dazu auch nix besseres ein.
Der Patternspace hält ja immer einen trailing slash.

Aber etwas simpler geht das mit dd, wenn die f-size bekannt ist.
Code:
$ cat dummy
Das ist meine Schreibmaschine
Die Zweite Zeile.
Ende
wolle@Nietzsche:~/temp
$ Z=$(wc -c dummy)
53 
wolle@Nietzsche:~/temp
$ dd if=dummy of=dummy1 bs=1 count=52
52+0 Datensätze ein
52+0 Datensätze aus
52 Bytes (52 B) kopiert, 0,00031157 Sekunden, 167 kB/s
wolle@Nietzsche:~/temp
$ cat dummy1
Das ist meine Schreibmaschine
Die Zweite Zeile.
Endewolle@Nietzsche:~/temp

Verallgemeinert könnte man nun in der Bash die Bytegröße mit e.g. wc ermitteln und diese um ein Byte reduziert an dd verfüttern.

Code:
$ Z=($(wc -c dummy)); 
echo $Z
53
dd if=dummy of=dummy1 bs=1 count=$((Z -1))
52+0 Datensätze ein
52+0 Datensätze aus
52 Bytes (52 B) kopiert, 0,00025128 Sekunden, 207 kB/s

Gruß Wolfgang
 

Ähnliche Themen

Hilfe für ein shell script

ip6tables Problem

Zeilen kopieren mit SED

SED letzte Zeile löschen

Probleme mit sed: im Text eine Zeile in Großbuchstaben ?

Zurück
Oben