2010-03-23 3 views

Antwort

9

Sie können nicht an den Anfang einer Datei anhängen, ohne Neuschreiben der Datei. Der erste Weg, den Sie angegeben haben, ist der richtige Weg.

0

Dank rechtem Suchbegriff!

echo "include .headers.java\n$(cat fileObject.java)" > fileObject.java 

dann mit einer Datei:

echo "$(cat .headers.java)\n\n$(cat fileObject.java)" > fileObject.java 
+2

Das enthält eine Racebedingung: manchmal (wenn nicht immer) richtet die Shell die Standardumleitung ein, die die Datei vorher auf Null setzt der zweite "cat" -Befehl ist abgeschlossen. – pra

+0

@pra: behoben? $ echo "$ (lese -t 1; Katze eins) \ n \ n $ (Katze zwei)"> eins? – hhh

1

Sie können nicht in einer Datei voranstellen, ohne den gesamten Inhalt der Datei zu lesen und eine neue Datei mit dem Text vorangestellt + Inhalt der Datei zu schreiben. Stellen Sie sich eine Datei in Unix als einen Bytestrom vor - es ist einfach, sie an ein Ende eines Streams anzuhängen, aber es gibt keine einfache Operation, um den Stream zurückzuspulen und darauf zu schreiben. Selbst eine Suchoperation am Anfang der Datei überschreibt den Anfang von Daten, die Sie schreiben.

3

Dies ist einfach in sed zu tun, wenn Sie die Header-Zeichenfolge direkt in dem Befehl einbetten können:

$ sed -i "1iheader1,header2,header3" 

Oder wenn Sie es wirklich aus einer Datei lesen möchten, können Sie dies mit bash Hilfe:

$ sed -i "1i$(<header)" file 

ACHTUNG, dass "-i" die Eingabedatei mit den Ergebnissen überschreibt. Wenn Sie möchten, dass sed ein Backup erstellt, ändern Sie es in "-i.bak" oder ähnliches und testen Sie immer zuerst mit Beispieldaten in einem temporären Verzeichnis, um sicher zu sein, dass Sie wissen, was passieren wird, bevor Sie Ihre realen Daten anwenden .

2

Die ganze Dummy-Datei ist ziemlich nervig. Hier ist eine 1-Liner-Lösung, die ich gerade ausprobiert habe und die zu funktionieren scheint.

Die Ticks machen den Teil in Anführungszeichen zuerst ausführen, so dass es sich nicht über die Ausgabedatei als Eingabedatei beschwert. Es scheint mit hhhs Lösung verwandt zu sein, aber ein bisschen kürzer. Ich nehme an, wenn die Dateien wirklich groß sind, könnte das zu Problemen führen, weil es so aussieht, als ob die Shell sich über die Ticks beklagen würde, die Befehle zu lange vorher gemacht haben. Irgendwo muss der Teil, der zuerst ausgeführt wird, in einem Puffer gespeichert werden, so dass das Original überschrieben werden kann, aber ich bin nicht genug von einem Experten, um zu wissen, was/wo dieser Puffer wäre oder wie groß er sein könnte.

+0

UPDATE: Dieser Ansatz scheint einige Quelldateien zerstört zu haben, denen ich einen Copyright-Hinweis voranstellen wollte. Es scheint beendet zu sein, als es in den Quelldateien einfache Anführungszeichen und in die Zeichen umgewandelte Escape-Sequenzen ansprach. Ich denke, es ist nicht so nützlich. – Rob

+0

AKTUALISIERUNG 2: Der Befehl scheint von der Befehlszeile aus zu funktionieren, interpretierte aber die Escape-Sequenzen aus einem Skript, mit dem ich viele Dateien gleichzeitig vorlegte. Ich dachte zuerst, dass es nicht das Standard-Echo -E verwendet, aber das hat es immer noch nicht behoben. Anscheinend hatte das Problem mit der Verwendung von '# \ bin \ sh' am Anfang des Skripts zu tun. Von einer 'sh' anstelle einer 'bash' Befehlszeile werden die Escape-Sequenzen immer interpretiert. Ich änderte mein Skript so, dass die erste Zeile stattdessen '# \ bin \ bash' war und die Dinge scheinen korrekt zu funktionieren. Moral: problematisch mit sh ... nicht sicher warum? – Rob

1

Eine Möglichkeit ist es, ein Hier-Dokument zu verwenden:

cat > "prependedfile" << ENDENDEND 
prepended line(s) 
`cat "file"` 
ENDENDEND 

eine Speicherbegrenzung auf diesen Trick sein kann.

0

, wenn Sie Pre-pend wollen "Header" auf "Datei" Warum hängen Sie nicht "Datei" auf "Header"

cat file >> header 
0

Im Folgenden ist ein einfacher c-Shell Versuch, dieses Problem zu lösen. Dies "vor.sh“Skript nimmt zwei Parameter:.

  • $ 1 - Die Datei mit der prä-Anhängen Formulierung enthält
  • $ 2 - Das Original/Zieldatei geändert werden
#!/bin/csh 
if (if ./tmp.txt) then 
    rm ./tmp.txt 
endif 

cat $1 > ./tmp.txt 
cat $2 >> ./tmp.txt 

mv $2 $2.bak 
mv ./tmp.txt $2 
Verwandte Themen