it-swarm.com.de

Unix-Befehl zum Voranstellen von Text an eine Datei

Gibt es einen Unix-Befehl, um einer Textdatei einige String-Daten voranzustellen?

So etwas wie:

prepend "to be prepended" text.txt
89
One Two Three
sed -i.old '1s;^;to be prepended;' inFile
  • -i schreibt die Änderung an Ort und macht eine Sicherung, 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 ; als Befehlsbegrenzer.
78
printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt
135
shime

Dies ist eine Möglichkeit:

(echo "to be prepended"; cat text.txt) > newfile.txt

sie werden wahrscheinlich nicht leicht eine Zwischendatei umgehen können.

Alternativen (kann bei Shell-Flucht umständlich sein):

sed -i '0,/^/s//to be prepended/' text.txt
26
0xC0000022L

Prozessersetzung

Ich bin überrascht, dass dies niemand erwähnt hat.

cat <(echo "before") text.txt > newfile.txt

was natürlich natürlicher ist als die akzeptierte Antwort (etwas drucken und in einen Ersetzungsbefehl leiten, ist lexikographisch kontraintuitiv).

... und hijacking was ryan oben gesagt hat, mit sponge brauchst du keine temporäre Datei:

Sudo apt-get install moreutils
<<(echo "to be prepended") < text.txt | sponge text.txt

BEARBEITEN: Anscheinend funktioniert das in der Bourne Shell nicht /bin/sh


Hier String

Mit einem Here-String - <<< (wiederum benötigen Sie eine Bash) - können Sie Folgendes tun:

<<< "to be prepended" < text.txt | sponge text.txt
22

Dadurch wird die Ausgabe erstellt. Die - bedeutet Standardeingabe, die über die Pipe vom Echo aus erfolgt.

echo -e "to be prepended \n another line" | cat - text.txt

Zum erneuten Schreiben der Datei ist eine temporäre Datei erforderlich, da sie nicht in die Eingabedatei zurückgeleitet werden kann.

echo "to be prepended" | cat - text.txt > text.txt.tmp
mv text.txt.tmp text.txt
15
Adam

Bevorzugen Sie Adams Antwort

Wir können die Verwendung von Schwamm vereinfachen. Jetzt müssen wir keine temporäre Datei erstellen und sie mit umbenennen 

echo -e "to be prepended \n another line" | cat - text.txt | sponge text.txt
11
ryan

Unter bestimmten Umständen ist der angefügte Text möglicherweise nur von stdin ..__ verfügbar.

echo "to be prepended" | cat - text.txt | tee text.txt

Wenn Sie die tee-Ausgabe weglassen möchten, fügen Sie > /dev/null an.

7
sehari24jam

Wahrscheinlich nichts eingebautes, aber Sie könnten ganz leicht Ihr eigenes schreiben:

#!/bin/bash
echo -n "$1" > /tmp/tmpfile.$$
cat "$2" >> /tmp/tmpfile.$$
mv /tmp/tmpfile.$$ "$2"

So etwas jedenfalls ...

7
Rob I

Lösung:

printf '%s\n%s' 'text to prepend' "$(cat file.txt)" > file.txt

Beachten Sie, dass dies für alle Arten von Eingaben sicher ist, da keine Erweiterungen vorhanden sind. Wenn Sie beispielsweise [email protected]#$%^&*()ugly text\n\t\n voranstellen möchten, funktioniert es einfach:

printf '%s\n%s' '[email protected]#$%^&*()ugly text\n\t\n' "$(cat file.txt)" > file.txt

Der letzte noch zu prüfende Teil ist das Entfernen von Leerzeichen am Dateiende während der Befehlsersetzung "$(cat file.txt)". Alle Problemumgehungen dafür sind relativ komplex. Wenn Sie Zeilenumbrüche am Ende von file.txt beibehalten möchten, finden Sie folgende Informationen: https://stackoverflow.com/a/22607352/1091436

6
VasiliNovikov

Wenn es akzeptabel ist, ersetzen die Eingabedatei:

Hinweis: kann unerwartete Nebenwirkungen haben, insbesondere Ersetzen eines Symlinks durch eine reguläre Datei, möglicherweise mit unterschiedlichen Berechtigungen für die Datei und Ändern des Erstellungsdatums der Datei

sed -i, wie in Prince John Wesleys Antwort , versucht, die ursprünglichen Berechtigungen zumindest wiederherzustellen, aber es gelten die anderen Einschränkungen.

 { printf 'line 1\nline 2\n'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt

Hinweis: Die Verwendung eines Gruppe Befehls { ...; ... } ist effizienter als die Verwendung eines Subshell ((...; ...)).


Wenn die input-Datei bearbeitet werden soll in place (wobei der Inode mit all seinen Attributen erhalten bleibt):

Verwenden des ehrwürdigen ed POSIX-Dienstprogramms :

Hinweis: ed liest immer die Eingabedatei als Ganzes zuerst in den Speicher.

ed -s text.txt <<'EOF' 
1i
line 1
line 2
.
w
EOF
  • -s unterdrückt eds Statusmeldungen.
  • Beachten Sie, wie die Befehle ed als mehrzeiliges here-document (<<'EOF' ... EOF) bereitgestellt werden, d. H. Über stdin.
  • 1i macht 1 (die 1. Zeile) zur aktuellen Zeile und startet den Einfügemodus (i).
  • Die folgenden Zeilen sind der Text, der vorher der aktuellen Zeile eingefügt werden soll, mit . in der eigenen Zeile.
  • w schreibt das Ergebnis zurück in die Eingabedatei (zum Testen ersetzen Sie w durch ,p in nur print das Ergebnis, ohne die Eingabedatei zu ändern).
5
mklement0

Eine andere Möglichkeit mit sed:

sed -i.old '1 {i to be prepended
}' inFile

Wenn die vorangestellte Zeile mehrzeilig ist:

sed -i.old '1 {i\ 
to be prepended\
multiline
}' inFile
3
Mert Nuhoglu

Wie in Bash (in Ubuntu) getestet, wenn mit einer Testdatei über gestartet wird;

echo "Original Line" > test_file.txt

du kannst 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 erhalte den folgenden Inhalt von "test_file.txt";

New Line
Original Line

Keine Zwischendatei, nur Bash/Echo.

3
AlexanderESmith

Eine andere recht einfache Lösung ist:

    $ echo -e "string\n" $(cat file)
2
Pat

Wenn du vi/vim magst, könnte dies mehr dein Stil sein.

printf '0i\n%s\n.\nwq\n' prepend-text | ed file
1
Ian Kelling
# create a file with content..
echo foo > /tmp/foo
# prepend a line containing "jim" to the file
sed -i "1s/^/jim\n/" /tmp/foo
# verify the content of the file has the new line prepened to it
cat /tmp/foo
0
Jim

Ich mochte keine der Antworten hier wirklich, also baute ich meinen eigenen Befehl: pre.

Mit go installieren:

go get -u github.com/Flaque/pre

Füge einen Text aus stdin mit einer der folgenden Dateien hinzu:

echo "some at the start" | pre myFile.txt | sponge myFile.txt

Der Befehl schreibt nicht an Ort und Stelle, er wird nur in stdout ausgegeben. Sie benötigen also die Variable sponge von moreutils, um die Datei zu speichern.

0
Evan Conrad

Ich würde empfehlen, eine Funktion zu definieren und diese dann wo nötig zu importieren und zu verwenden.

prepend_to_file() { 
    file=$1
    text=$2

    if ! [[ -f $file ]] then
        touch $file
    fi

    echo "$text" | cat - $file > $file.new

    mv -f $file.new $file
}

Dann benutze es wie folgt:

prepend_to_file test.txt "This is first"
prepend_to_file test.txt "This is second"

Ihr Dateiinhalt lautet dann:

This is second
This is first

Ich bin dabei, diesen Ansatz zum Implementieren eines Änderungsprotokoll-Aktualisierungsprogramms zu verwenden.

0
AwesomeBobX64