sonnenblen.de - Das unabhängige Sun User Forum

Software => Programmieren, Kompilieren => Thema gestartet von: signal_15 am 01. April 2009, 11:02:38

Titel: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 01. April 2009, 11:02:38
Hi,

bin auf der suche nach einer einfachen methode um eine zeile text in eine datei oben am anfang rein zu schreiben.
ein
  echo "bla blub" >> /irgendwo/datei
schreibt mir den inhalt an das ende der datei. ich moechte aber den bisherigen inhalt der datei um zeile nach unten verschieben und den inhalt oben drauf geben. hat da jemand eine idee?

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: Octane_Suicide am 01. April 2009, 12:25:03
Hallo,

vielleicht die Zeile in eine Datei schreiben und den umgekehrten Weg gehen?
Also das Ziel-File an das File mit der einen Zeile haengen und am Ende den Dateinamen aender...
Glaub das sollte gehen, oder?

MfG Michael
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 01. April 2009, 15:52:20
habs nun folgendermasen gemacht:
echo "bla blup" >> $temp1
cat $datei >> $temp1
cat $temp1 > $datei

ein einzeiler waere mir aber trotzdem lieber gewesen. so muss cat zwei mal laufen und auf dauer, wenn die datei groesser wird, wird's immer langsamer.

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: dominik am 01. April 2009, 16:17:47
ein einzeiler waere mir aber trotzdem lieber gewesen. so muss cat zwei mal laufen und auf dauer, wenn die datei groesser wird, wird's immer langsamer.

Geht doch:

echo "bla blup" >> $temp1; cat $datei >> $temp1; cat $temp1 > $datei

Gruss
Dominik
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 01. April 2009, 16:38:29
@dominik
der war gut.-)

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: dornroeschen am 01. April 2009, 16:44:18
Dem Editör is nix zu schwör  ;D
/usr/bin/echo '0a\nbla blub\n.\nw\nq' | ed -s $datei

Rainer
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 01. April 2009, 16:48:41
@dornroeschen
na also, geht doch. sieht doch schon mal recht vielversprechend (oder heisst es 'viel versprechend') aus. ich glaub nicht, dass ich das script noch heute anpassen werde. aber ich gebe dann bescheid.

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: mdjr am 02. April 2009, 07:41:29
Dem Editör is nix zu schwör  ;D
/usr/bin/echo '0a\nbla blub\n.\nw\nq' | ed -s $datei

Rainer

Hallo.

Das wird allerdings bei großen Dateien nicht funktionieren.

Das "unten dran-Hängen" ist eine Operation, die jedes Betriebssystem von sich aus unterstützt. Ein direktes "oben dran-Kleben" ist bei den mir bekannten Dateisystemen (FAT, NTFS, UFS, EXT2) wohl unmöglich.

Die Datei muss beim "oben dran-Kleben" also komplett neu geschrieben werden. Dazu gibt es zwei Möglichkeiten:
- Die zwei-Dateien-Lösung
- Die Datei komplett in den RAM lesen und dann schreiben (Lösung mit dem "ed"-Editor)

Da bei großen Dateien aber nicht genügend RAM zur Verfügung steht, ist das ein Problem.

habs nun folgendermasen gemacht:
echo "bla blup" >> $temp1
cat $datei >> $temp1
cat $temp1 > $datei

Mehr Performance würde der folgende Code bringen, da kein zweites Umkopieren notwendig ist:
echo "bla blup" > $temp1
cat $datei >> $temp1
rm $datei
mv $temp1 $datei
(Allerdings gehen dabei UID, GID, Mode, ... von "$datei" verloren)

Martin
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 02. April 2009, 09:11:32
@Martin

richtig. und ich brauche/habe folgendes:
total 46K
drwxr--r--  2 root   other  512 Apr  1 16:35 .
drwxr-xr-x 14 root   other 1.0K Mar 31 14:02 ..
-rw-r--r--  1 daemon other 7.1K Apr  1 16:50 index.shtml
-rw-r--r--  1 root   other  12K Apr  1 14:22 index.shtml_Backup_2009_04_01
-rw-r--r--  1 daemon other 6.3K Apr  1 16:50 news-db
-rw-r--r--  1 root   other 1.2K Apr  1 14:37 test.shtml

man koennte das script als 'daemon' laufen lassen. aber dann muesste auch das verzeichnis dieser uid gehoeren, oder zumindest die schreib/lese-rechte geaendern werden. und das soll nicht sein.

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: dornroeschen am 02. April 2009, 10:19:37
Dem Editör is nix zu schwör  ;D
/usr/bin/echo '0a\nbla blub\n.\nw\nq' | ed -s $datei

Rainer

Hallo.

Das wird allerdings bei großen Dateien nicht funktionieren.

Völlig richtig. Jede Lösung ist gut/nicht gut bzw geht/geht nicht nur im Rahmen der bekannten/nicht bekannten Randbedingungen. Ich finde den ed  als Skripting Tool für Inline-Editing ganz interessant, solange klar ist, dass die Begrenzungen des Tools nicht überschritten werden. Beim Solaris ed sind dies die maximale Zeilenlänge von 512 Zeichen, und die Begrenzung der Zeilen durch die Speichergröße. Wie die Beschränkungen des GNU-ed aussehen, weiss ich jetzt nicht.

Alternativ kann man identisch auch den ex (vi) einsetzen, oder die ex-Variante des vim. Ich glaube nicht, dass vim oder auch nvi eine Beschränkung der Zeilenlänge haben.

Rainer
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: llothar am 02. April 2009, 11:28:36
Ja hier sehen wir wieder mal das Problem das Filesysteme vom Programmiertechnischen sich seit fast 30 Jahren nicht verändert haben. Eine Datei als Queue die vorne und hinten anfügen und entfernen unterstützt und das reinschiessen von Löchern (Sparse Files) ist eigentlich so sinnvoll.

Aber egal. Ich würde gerne wissen wozu du das brauchst. Denn ich denke du setzt falsch an. Vorne und hinten sind technisch irgendwie gleich. Wenn es wegen anzeige der Daten ist ändere die Datenanzeige.

Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: meik am 02. April 2009, 12:51:08
habs nun folgendermasen gemacht:
echo "bla blup" >> $temp1
cat $datei >> $temp1
cat $temp1 > $datei

ein einzeiler waere mir aber trotzdem lieber gewesen. so muss cat zwei mal laufen und auf dauer, wenn die datei groesser wird, wird's immer langsamer.

Bei der Größenordnung würde ich mir um Performance keine Gedanken machen. Ein paar kB machen auf einem Rechner mit Gigabytes an RAM wirklich kein Problem.

Sollte das wirklich in messbare Regionen kommen, wirst du wahrscheinlich sowieso messen müssen, welche Variante die beste ist.

Was mir sonst noch eingefallen ist:

Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 02. April 2009, 13:00:35
$llothar

ich habe ein shell skript als cgi auf einem apachen laufen, welches neue nachrichten aus einem webformular zuerst in eine plain-text datei schreibt und diese dann in eine html seite einfuegt.

#!/bin/sh
# create entry on the news page

umask=022
grep=/usr/bin/grep
awk=/usr/local/bin/awk
cat=/usr/local/bin/cat
temp1=/tmp/tmp.$$
temp2=/tmp/tmp.$$
mdate=`date "+%d %B %Y"`
mtime=`date "+%H:%M"`
newsdb=/var/www/news/news-db
newsindex=/var/www/news/index.shtml
newsheader=/var/www/news/news-header
newsfooter=/var/www/news/news-footer
eval `/usr/local/bin/proccgi.sh $*`

# build the news-db
echo "<tr><td>$mdate</td><td>$mtime</td><td></td><td><b>$FORM_ueberschrift</b></td></tr>" >> $temp1
echo "<tr><td>      </td><td>      </td><td></td><td>$FORM_nachricht <br><br></td></tr>" >> $temp1
$cat $newsdb >> $temp1
$cat $temp1 > $newsdb

# build the page
/usr/local/bin/cat $newsheader > $newsindex
/usr/local/bin/cat $newsdb >> $newsindex
/usr/local/bin/cat $newsfooter >> $newsindex

# clean up
rm -r $temp1

echo "Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<body><p>yeah, check the news site</p></body></html>"
exit 0

ct,

Edith sagt: Name falsch geschrieben.
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: llothar am 02. April 2009, 13:49:37
$llothar

ich habe ein shell skript als cgi auf einem apachen laufen, welches neue nachrichten aus einem webformular zuerst in eine plain-text datei schreibt und diese dann in eine html seite einfuegt.

So was hab ich mir gedacht. Da du die Datei ja sowieso komplett liest häng es unten dran und mach ein "reverse" und beim dranhängen dann natürlich auch noch ein reverse. Man kann mittels tail -n auch die letzten zeilen ausgeben.

Vorne dran hängen würde ich nichts. Umkopieren ist viel aufwendiger als lesen und umdrehen.
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 02. April 2009, 13:51:51
@llothar
jetzt habe ich deinen faden verloren. wie meinen?

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: Toktar am 02. April 2009, 20:07:36
Was ist denn gegen tac zu sagen. Damit gibst Du den Inhalt rückwärts aus und kannst die neuen Zeilen unten dranhängen....
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: llothar am 02. April 2009, 23:17:55
@llothar
jetzt habe ich deinen faden verloren. wie meinen?

Ich bin jetzt nicht der Shell Scripter aber irgendwas wie


cat neue_nachricht.txt | reverse -l  >> datei_mit_allen_nachrichten.txt

sowie

tail -n 100 datei_mit_allen_nachrichten.txt | reverse -l


"reverse -l" ist jetzt aber ein selbstgeschriebenes Tool. Hab gerade kein Unix am
laufen um zu sehen wie der Parmaeter wirklich heisst. "reverse -l" nimmt die
Eingabe entgegen und gibt sie umgekehrt wieder aus, mit option "-l" basierend
auf Zeilenbasis.

Mit obigem würdest du in der ersten Zeile halt eine Nachrichten  an dein Nachrichten  Log anhängen.
Und mit der zweiten Zeile die letzten 100 Zeilen aller Nachrichten ausgeben.

Komplexität ist immer O(n) mit n der Grösse der hinzufügenden Nachricht und der Anzahl der
Zeilen die du im CGI script ausgeben würdest.  Selbst wenn deine Datei in der du die
Nachrichten sammelst Gigabyte gross wird ist das also noch extrem performant.

Edit:
Erst jetzt sehe ich das Toktar geantwortet hat.
Statt reverse also "tac" nutzen und fertig.
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: dornroeschen am 03. April 2009, 11:33:25
Erst jetzt sehe ich das Toktar geantwortet hat.
Statt reverse also "tac" nutzen und fertig.

oder /usr/bin/tail -r  ;D

Rainer
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 09. April 2009, 09:26:27
Guten Morgen,

ich bin jetzt bei meiner ersten version geblieben. sie funktioniert wie geplant und laeuft auch schnell genug.
# build the news-db
echo "<tr><td>$mdate</td><td>$mtime</td><td></td><td><b>$FORM_ueberschrift</b></td></tr>" >> $temp1
echo "<tr><td>      </td><td>      </td><td></td><td>$FORM_nachricht <br><br></td></tr>" >> $temp1
$cat $newsdb >> $temp1
$cat $temp1 > $newsdb

# build the page
/usr/local/bin/cat $newsheader > $newsindex
/usr/local/bin/cat $newsdb >> $newsindex
/usr/local/bin/cat $newsfooter >> $newsindex

das ganze mit 'tail -r' oder reverse, haette gar nicht mal so leicht geklappt da die neuen eintraege mehrzeilig sind und bei einem 'tail -r' dann alles durcheinander gewuerfelt worden waere.

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: meik am 09. April 2009, 13:53:40
Guten Morgen,

ich bin jetzt bei meiner ersten version geblieben. sie funktioniert wie geplant und laeuft auch schnell genug.

Ich bin der festen Überzeugung, dass die meisten vorausschauenden Optimierungen gar nicht nötig sind. ;-)

So ad hoc würden mir noch die folgenden Änderungen einfallen:
Zitat
# build the news-db
echo "<tr><td>$mdate</td><td>$mtime</td><td></td><td><b>$FORM_ueberschrift</b></td></tr>" > $temp1
echo "<tr><td>      </td><td>      </td><td></td><td>$FORM_nachricht <br><br></td></tr>" >> $temp1
$cat $newsdb >> $temp1
mv $temp1 $newsdb

# build the page
/usr/local/bin/cat $newsheader $newsdb $newsfooter > $newsindex

Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 09. April 2009, 14:01:29
temp1=/tmp/temp.$$
somit ist das file garantiert angelegt.

/usr/local/bin/cat $newsheader $newsdb $newsfooter > $newsindex
gefaellt mir gut und werde ich so uebernehmen.

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: meik am 09. April 2009, 14:57:04
temp1=/tmp/temp.$$
somit ist das file garantiert angelegt.
Das ist ja nur der Filename, was passiert, wenn z.B. bei einem lange laufenden System die Pid zum zweiten Mal vergeben wird? Ist zugegebenermassen unwahrscheinlich, aber ich würde dennoch das erste >> in ein > wandeln, damit wird das File entweder neu angelegt oder zumindestens der alte Inhalt gelöscht.

BTW: Wäre auch noch zu überlegen, ob du $temp1 nicht zum Schluß löschst, damit in /tmp nicht zu viel Müll liegen bleibt.
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 09. April 2009, 15:02:44
am ende des scripts laeuft ein 'rm -r $temp1', somit habe ich das tmp-verzeichnis vor vermuellung verschont und sichergestellt, dass die tmp-datei wieder garantiert leer sein wird.-)

aber ich sehe schon, du willst das erste >> durch ein > unbedingt ersetzt sehen.-) werde ich machen.

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: llothar am 09. April 2009, 16:26:01
das ganze mit 'tail -r' oder reverse, haette gar nicht mal so leicht geklappt da die neuen eintraege mehrzeilig sind und bei einem 'tail -r' dann alles durcheinander gewuerfelt worden waere.

Schau dir noch mal meine Lösung an.
Das war mir schon bewusst.

Deshalb must du ja vor dem Anhängen ein reverse auf die Nachricht machen,
denn reverse + reverse ist wie not + not oder Merkel + Steinmüller, alles ist null und leere Luft.
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: signal_15 am 09. April 2009, 16:32:50
@llothar
ich hab gerade eben 'm meik zugesagt seinen vorschlag mit einzubinden. jetzt kommst du wieder mit deinem 'reverse + reverse' daher. da kann dann jeder daher kommen und ne aenderung haben wollen. und am ende erkenne ich mein eigenes skript nicht mehr.-)

mal sehen. im moment gefaellt mir das skript so wie es ist ganz gut. es ist einfach gehalten und wenn ich in zwei jahren rein sehe werde ich auch ohne doku und komentare erkennen koennen was ich mir heute dabei gedacht habe.

aber trotzdem ein dickes danke an alle fuer die brauchbaren vorschlaege.

ct,
Titel: Re: nicht unten dran-haengen sondern oben drauf-kleben
Beitrag von: linuxdomination am 05. Mai 2009, 16:11:22

"reverse -l" ist jetzt aber ein selbstgeschriebenes Tool.


muaaahahahaa, ist ja toll das du so ein selbstgeschriebenes wasauchimmer hast, wird weder den op noch sonstirgendwen irgendwie weiterbringen *gg*

/schizo off