Gibt es einen Unix-Befehl, um einer Textdatei einige Zeichenfolgendaten voranzustellen?
Etwas wie:
prepend "to be prepended" text.txt
unix
command-line
utilities
prepend
Eins zwei drei
quelle
quelle
<<(echo "to be prepended") < text.txt | sponge text.txt
Antworten:
-i
schreibt die Änderung an Ort und Stelle und erstellt ein Backup, wenn eine Erweiterung angegeben wird. (In diesem Fall.old
)1s;^;to be prepended;
Ersetzt den Anfang der ersten Zeile durch die angegebene Ersetzungszeichenfolge und verwendet sie;
als Befehlsbegrenzer.quelle
\n
nach dem Voranstellen einfügen . je nach ihren Bedürfnissen. Ordentliche Lösung.inFile
Include-Verzeichnisse in ihren Pfad aufgenommen werden?\n
. Hätte zuerst die Kommentare lesen sollen. Verdammt.'1s;^;my-prepended-line\;\n;'
quelle
git config --get-regex $arg | sed -r 's/\t{3}/\\n/g';
und dies bringt es durcheinander, wenn es das\t
und konvertiert\n
.echo "to be prepended"$'\n'"$(cat text.txt)"
Prozesssubstitution
Ich bin überrascht, dass niemand dies erwähnt hat.
Das ist wohl natürlicher als die akzeptierte Antwort (etwas zu drucken und in einen Substitutionsbefehl zu leiten, ist lexikographisch kontraintuitiv).
... und entführen, was Ryan oben gesagt hat,
sponge
ohne dass Sie eine temporäre Datei benötigen:EDIT: Sieht so aus, als würde dies in Bourne Shell nicht funktionieren
/bin/sh
Hier String (nur zsh)
Mit einem Here-String -
<<<
können Sie Folgendes tun:quelle
<<(echo "to be prepended") < text.txt
und<<< "to be prepended" < text.txt
Konstruktionen funktionieren nicht in Bash; sie benötigen zsh.Dies ist eine Möglichkeit:
Sie werden wahrscheinlich nicht leicht um eine Zwischendatei herumkommen.
Alternativen (können umständlich sein, wenn die Schale entweicht):
quelle
cat <(echo "to be prepended") text.txt > newfile.txt
. Wenn ich darüber nachdenke, bin ich mir nicht sicher, ob meine verwandt ist, also poste ich eine separate Antwort.Dies wird funktionieren, um die Ausgabe zu bilden. Das - bedeutet Standardeingang, der über die Pipe vom Echo bereitgestellt wird.
Zum Umschreiben der Datei ist eine temporäre Datei erforderlich, die nicht in die Eingabedatei zurückgeleitet werden kann.
quelle
text.txt
wie gewünscht vorangestellt, sondern auf stdout angezeigt. Die Ausgabe könnte in eine andere Datei geleitet werden, wenn dies für das OP funktioniertBevorzugen Sie Adams Antwort
Wir können die Verwendung von Schwamm vereinfachen . Jetzt müssen wir keine temporäre Datei erstellen und umbenennen durch
quelle
Wenn es akzeptabel ist, die Eingabedatei zu ersetzen :
Hinweis:
Dies kann unerwartete Nebenwirkungen haben, insbesondere das Ersetzen eines Symlinks durch eine reguläre Datei, das Erhalten unterschiedlicher Berechtigungen für die Datei und das Ändern des Erstellungsdatums (des Geburtsdatums) der Datei.
sed -i
Wie in der Antwort von Prince John Wesley wird versucht, zumindest die ursprünglichen Berechtigungen wiederherzustellen, es gelten jedoch auch die anderen Einschränkungen.Hier ist eine einfache Alternative, bei der eine temporäre Datei verwendet wird (es wird vermieden, dass die gesamte Eingabedatei wie bei der Shime-Lösung in den Speicher eingelesen wird):
Die Verwendung eines Gruppenbefehls (
{ ...; ...; }
) ist etwas effizienter als die Verwendung einer Unterschale ((...; ...)
), wie in der Lösung von 0xC0000022L .Die Vorteile sind:
Es ist einfach zu steuern, ob der neue Text direkt der ersten Zeile vorangestellt oder als neue Zeile (n) eingefügt werden soll (einfach
\n
an dasprintf
Argument anhängen ).Im Gegensatz zur
sed
Lösung funktioniert es, wenn die Eingabedatei leer ist (0
Bytes).Die
sed
Lösung kann vereinfacht werden, wenn dem vorhandenen Inhalt eine oder mehrere ganze Zeilen vorangestellt werden sollen (vorausgesetzt, die Eingabedatei ist nicht leer):sed
'si
Funktion fügt ganze Zeilen ein:Mit GNU
sed
:Eine tragbare Variante, die auch mit macOS / BSD funktioniert
sed
:Beachten Sie, dass der wörtliche Zeilenumbruch nach dem
\
erforderlich ist.Wenn die Eingabedatei an Ort und Stelle bearbeitet werden muss (wobei der Inode mit all seinen Attributen beibehalten wird):
Verwenden des ehrwürdigen
ed
POSIX-Dienstprogramms :Hinweis:
ed
Liest immer zuerst die gesamte Eingabedatei in den Speicher.So stellen Sie direkt in die erste Zeile voran (wie bei
sed
funktioniert dies nicht, wenn die Eingabedatei vollständig leer ist (0
Bytes)):-s
ed
Statusmeldungen von unterdrückt .ed
als mehrzeiliges here-document (<<EOF\n...\nEOF
) bereitgestellt werden , dh über stdin ; Standardmäßig wird in solchen Dokumenten eine Zeichenfolgenerweiterung durchgeführt (Shell-Variablen werden interpoliert). zitieren Sie den Eröffnungsbegrenzer, um dies zu unterdrücken (z<<'EOF'
. B. ).1
macht die 1. Zeile zur aktuellen Zeiles
führt eine Regex-basierte Zeichenfolgenersetzung in der aktuellen Zeile durch, wie insed
; Sie können wörtliche Zeilenumbrüche in den Ersetzungstext aufnehmen, diese müssen jedoch\
umgangen werden.w
schreibt in die Eingabedatei das Ergebnis zurück (für die Prüfung, ersetzenw
mit,p
nur drucken das Ergebnis, ohne die Eingabedatei zu verändern).So stellen Sie eine oder mehrere ganze Zeilen voran :
Wie bei fügt
sed
diei
Funktion dem einzufügenden Text immer eine nachgestellte neue Zeile hinzu.0 i
macht0
(den Anfang der Datei) zur aktuellen Zeile und startet den Einfügemodus (i
); Beachten Sie, dass die Zeilennummern ansonsten1
basieren..
einer eigenen Zeile abgeschlossen wird.quelle
Wahrscheinlich ist nichts eingebaut, aber Sie könnten ganz einfach Ihre eigenen schreiben:
Zumindest so etwas ...
quelle
$$
ist jedoch für Produktionscode nicht ausreichend (Google Symlink-Angriff). aber es ist sicherlich besser als ein statischer Dateiname.mktemp
Unter bestimmten Umständen ist vorangestellter Text möglicherweise nur bei stdin verfügbar. Dann soll diese Kombination funktionieren.
Wenn Sie die
tee
Ausgabe weglassen möchten , fügen Sie sie hinzu> /dev/null
.quelle
tee
die nicht verstopft,text.txt
bevorcat
man sie lesen kann? Ich denke nicht - was diese Lösung für die Gesundheit der Datei gefährlich machen würde.lenA=1000000; yes a | head -c $lenA > a.txt; lenB=10000; b=$(yes b | head -c $lenB); echo "$b" | cat - a.txt | tee a.txt > /dev/null
. WennlenA
1000000 (1 MB Datei) undlenB
10000 (10 KB Text vorangestellt) ist, wird die Datei "a.txt" mit 20 KB "b" Buchstaben überschrieben. Das ist total kaputt. Wenn Sie jetzt 1 MB a.txt und 1 MB Text zum Voranstellen verwenden undtee
in eine Schleife gehen , die eine 7 GB + -Datei generiert, musste ich den Befehl stoppen. Es ist also offensichtlich, dass das Ergebnis für große Größen nicht vorhersehbar ist. Ich habe keine Informationen, ob es bei kleinen Größen funktionieren soll.Lösung:
Beachten Sie, dass dies für alle Arten von Eingaben sicher ist, da keine Erweiterungen vorhanden sind. Wenn Sie beispielsweise voranstellen möchten,
!@#$%^&*()ugly text\n\t\n
funktioniert dies nur:Der letzte Teil, der berücksichtigt werden muss, ist das Entfernen von Leerzeichen am Ende der Datei während der Befehlsersetzung
"$(cat file.txt)"
. Alle Workarounds hierfür sind relativ komplex. Wenn Sie Zeilenumbrüche am Ende von file.txt beibehalten möchten, lesen Sie Folgendes: https://stackoverflow.com/a/22607352/1091436quelle
file.txt
größer ist, als in die Argumentliste aufgenommen werden kannprintf
.Ein anderer Weg mit
sed
:Wenn die vorangestellte Zeile mehrzeilig ist:
quelle
sed -i '1ito be prepended' inFile
- oder ist es nur für GNU sed erlaubt?sed
deni
Befehl ein Backslash und eine Newline, und jede Eingabezeile mit Ausnahme der letzten endet ebenfalls mit einem Backslash. GNUsed
erlaubt Abkürzungen in der Richtung, nach der Sie fragen, aber nur GNUsed
tut dies. 'Wie in Bash (in Ubuntu) getestet, wenn mit einer Testdatei über begonnen wird;
echo "Original Line" > test_file.txt
Sie können ausführen;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
oder wenn die Version von bash für $ () zu alt ist, können Sie Backticks verwenden;
echo "`echo "New Line"; cat test_file.txt`" > test_file.txt
und den folgenden Inhalt von "test_file.txt" erhalten;
Keine Zwischendatei, nur Bash / Echo.
quelle
Eine andere ziemlich einfache Lösung ist:
quelle
cat
Parametererweiterung nicht in doppelte Anführungszeichen zu setzen, ist ein ziemlich guter Grund für eine Abwertung . Dieser Code teilt den Inhalt der Datei in Wörter auf und übergibt jedes dieser Wörter als separates Argument anecho
. Sie verlieren die ursprünglichen Argumentgrenzen, Sie verlieren Zeilenumbrüche / Tabulatoren / etc. Und Zeichenfolgen wie\t
und\n
im Originaltext werden durch Tabulatoren und Zeilenumbrüche ersetzt, anstatt so zu bleiben, wie sie waren.Wenn Sie vi / vim mögen, ist dies möglicherweise eher Ihr Stil.
quelle
quelle
Ich würde empfehlen, eine Funktion zu definieren und diese dann zu importieren und bei Bedarf zu verwenden.
Dann benutze es so:
Ihr Dateiinhalt lautet dann:
Ich werde diesen Ansatz für die Implementierung eines Änderungsprotokoll-Updaters verwenden.
quelle