Bash – Wie kann ich am Anfang einer Textdatei eine Zeichenfolge hinzufügen, ohne sie vollständig zu lesen?

Bash – Wie kann ich am Anfang einer Textdatei eine Zeichenfolge hinzufügen, ohne sie vollständig zu lesen?

ich versuche, vor einer Textdatei mit dem Namen „test.txt“ die Zeichenfolge „Hallo Welt“ einzufügen. Ich mache das bereits mit sed, aber leider zerstört der „Sed-Befehl“ meinen Speicher, weil er eine ganze Datei liest.

meine Datei enthält einen 1 GB großen Text und mein Speicher hat nur 512 MB. Wie kann ich das machen? Ungefähr so:

echo --insert-before "hello world" >> test.txt

Oder mit welchem ​​Operator ich es vorher einfügen muss, etwa so:

echo "hello world" << test.txt

Oder eine andere Idee?

Hinweis: Der Operator >>zum Einfügen von Text am Ende funktioniert einwandfrei und raubt mir nicht den Speicher, aber ich muss ihn für den Anfang der Datei umgekehrt ausführen, ohne den Inhalt meiner Textdatei zu überschreiben, ohne neue Zeile.

hier ist mein tatsächlicher Code, den ich verwendet habe:

echo "hello world" > test.txt;
echo "the large content that size is 1gb" >> test.txt;
sed -i ':a;N;$!ba;s/\n//g' test.txt;

Antwort1

Sie geben an, dass Sie die folgende Befehlsfolge verwendet haben:

echo "hello world" > test.txt;
echo "the large content that size is 1gb" >> test.txt;
sed -i ':a;N;$!ba;s/\n//g' test.txt;

Ich gehe davon aus, dass die Befehle tatsächlich waren:

echo "hello world" > newfile;
cat test.txt >> newfile;            # assuming the file with 1GigaByte was test.txt

Und Sie beschweren sich über den sed-Befehl, der nur dazu da ist, Zeilenumbrüche zu entfernen (aus Ihrer Beschreibung).

Dasselbe könnte mit gemacht werden, trwas (nicht viel) Speicher verbraucht:

echo "hello world" > newfile;
cat test.txt | tr -d '\n' >> newfile

Und newfilees wird eine Kopie von test.txt mit vorangestelltem „Hallo Welt“ geben.

Antwort2

sedverwendet nicht viel Speicher. Das Betriebssystem kann jedoch die Festplatte zwischenspeichern. Daher nocachekann die Verwendung von hilfreich sein (wenn die Festplatte schnell genug ist oder Sie dieselben Daten nicht mehr als einmal lesen). Und/oder verwenden Sie die --unbufferedOption von sed(damit sedrely so wenig Speicher wie möglich verwendet).

Außerdem darf es keine Option zum Echo geben, da dies >>von der Shell und nicht vom Befehl ausgeführt wird. Es weist die Shell an, die Standardausgabe des Befehls an die Datei anzuhängen.

Und wie @Kusalananda sagt, sedist Ihr Skript nicht effizient. Ich würde wahrscheinlich einfach cat verwenden.

uncache cat "<(echo the_prefix)" old_file_name > new_file_name
rm old_file_name
mv -T new_file_name old_file_name #note not all `mv`s have the `-T` option, it can unsafely be left out.

Antwort3

Wie wäre es mit etwas Einfacherem?

cat <<_eof_ > file
Hello world!
$(cat file)
_eof_

Oder verwenden Sie ed

echo '0a
your text here
.
w' | ed some_file

Antwort4

Wenn dies Ihr Gedächtnis schädigt:

sed -i ':a;N;$!ba;s/\n//g' "test.txt"

Um dann Zeilenumbrüche zu entfernen, aber immer nur eine auf einmal zu lesen, versuchen Sie Folgendes:

{
    printf "hello world"  # with no newline
    while IFS= read -r line || [ -n "$line" ]; do
        printf "%s" "$line"
    done < test.txt
    echo ""          # add a newline to the end of the file
} > test.txt.tmp && mv test.txt{.tmp,}

Dies ist unter normalen Umständen etwas langsamer als sed, Ihre Situation liegt jedoch außerhalb des Alltäglichen.

verwandte Informationen