Antworten:
Sie können verwenden sed
:
sed -i 's/^/your_string /' your_file
Beachten Sie, dass die -i
Option dank der Kommentare von Stephane und Marco nicht POSIX ist. Ein POSIX-Weg, um das oben genannte zu tun, wäre
sed 's/^/your_string /' your_file > tmp_copy && mv tmp_copy your_file
oder perl
:
perl -pi -e 's/^/your_string /' your_file
Erläuterung
Beide Befehle führen eine Regex-Ersetzung durch und ersetzen den Anfang einer Zeile ( ^
) durch die gewünschte Zeichenfolge. Der -i
Schalter in beiden Befehlen stellt sicher, dass die Datei an Ort und Stelle bearbeitet wird (dh die Änderungen werden in der Datei wiedergegeben, anstatt in stdout gedruckt zu werden).
sed
sollte auf jedem POSIX-kompatiblen Betriebssystem perl
verfügbar sein und sollte auf den meisten modernen Unices verfügbar sein, außer vielleicht auf denen, die sich die Mühe gemacht haben , es zu entfernen.
sed -i
ist nicht POSIX. Es ist GNU. FreeBSD sed
hat eine ähnliche Option, aber Sie brauchen sed -i ''
dort.
-i
eine temporäre Kopie erstellt (das ist , warum ich sagte , werden die Änderungen reflektiert in der Originaldatei); Ich meinte, dass Sie die gleiche Semantik wie bei der In-Place-Substitution erhalten. Bitte überprüfen Sie, ob die aktualisierte Antwort POSIX-kompatibel ist.
$$
(die Prozess-ID der aktuellen Shell) als Teil eines temporären Dateinamens. Es vermeidet die Mühe, jedes Mal an einen garantierten eindeutigen Namen zu denken:command filename > filename.$$ && mv filename.$$ filename
:|paste -d'foo ' - - - - input > output
(nur ein Scherz, obwohl Sie wahrscheinlich feststellen werden, dass es die schnellste aller hier veröffentlichten Lösungen ist: -b).
Der kanonische Weg ist:
sed 's/^/foo /' < input > output
Es ist jedoch nicht einfach an beliebige Zeichenfolgen anzupassen. Zum Beispiel,
sed "s/^/$var /"
Dies funktioniert nur , wenn $var
nicht enthält, &
, \
, /
noch Zeilenumbrüche.
In jener Hinsicht,
export var
awk '{print ENVIRON["var"], $0}'
oder
perl -pe '$_="$ENV{var} $_"'
würde besser funktionieren.
Ich präsentiere eine Lösung, indem awk
ich den String "foo" voranstelle.
awk '{ print "foo", $0; }' input > output
awk
ist plattformübergreifend und auf jedem POSIX-System verfügbar. Es wird keine direkte Bearbeitung durchgeführt. Wenn Sie eine Datei bearbeiten möchten, ohne eine zweite zu erstellen, müssen Sie eine temporäre Datei verwenden. Siehe Josephs sed
Antwort, sie zeigt die Syntax. Ein weiterer Hack besteht darin, die folgende Syntax zu verwenden, mit der im Grunde genommen eine temporäre Datei mit demselben Dateinamen wie die Originaldatei erstellt wird.
{ rm file; awk '{ print "foo", $0 }' > file; } < file
reducto# wc -l foo
`914 foo` reducto# { rm foo ; awk '{ print "prepend" , $0 }' > foo } < foo
>
Das scheint nicht zu funktionieren. Ich habe es versucht, weil mich die Umleitung zum Original nervös gemacht hat, aber es wird nicht einmal anfangen.
Sie können die Probleme der direkten Bearbeitung mit den Stream-Tools vermeiden, indem Sie ein Tool verwenden, das normalerweise die direkte Bearbeitung durchführt - einen Editor!
ex sample.txt -c "%s/^/foo /" -c wq
Es gibt einen zusätzlichen Vorteil, dass die Befehle für jeden, der sich mit dem einen wahren Editor auskennt, einfach und offensichtlich sind.
Sie können dies verwenden perl
, um dies zu tun:
$ perl -pi -e 's/^/mystring /' afile.txt
Erstellen Sie eine Beispieldatei.
$ seq 5 > afile.txt
$ cat afile.txt
1
2
3
4
5
Führen Sie den obigen Befehl aus:
$ perl -pi -e 's/^/mystring /' afile.txt
$ cat afile.txt
mystring 1
mystring 2
mystring 3
mystring 4
mystring 5
sed
, wie man Perl benutzt ... ich habe gezeigt, wie man Perl benutzt ... ohne nach einem heiligen Krieg in dieser Angelegenheit zu suchen.
Einfach mit Bash
while IFS= read -r line; do echo "foo" "${line}" ; done < input > Output
Python verwenden
python -c "import sys; print 'foo '.join([ l for l in sys.stdin.readlines() ])" < input > Output
Wenn Sie direkt bearbeiten möchten
import fileinput
import sys
for line in fileinput.input(['inputfile'], inplace=True):
sys.stdout.write('foo {l}'.format(l=line))
awk
bei sehr kleinen Dateien. Das Verhalten variiert je nach Echo-Implementierung, entfernt führende und nachfolgende Leerzeichen und verarbeitet Backslashes speziell.
prefix () { while IFS= read -r REPLY; do printf "%s%s\n" "$1" "$REPLY"; done; }
sollte korrekter sein.
{}
? Ich denke, @Matt hat vorgeschlagen, dass Sie es zu einer benannten Funktion machen. Was bringt es {}
ohne einen Funktionsnamen?
Oder Sie können Folgendes tun:
vi filename.txt
Esc(um sicherzustellen, dass Sie sich im NORMAL
Modus befinden), und geben Sie dann den folgenden Befehl ein:
:1,$ s/^/mystring
1,$
einfach ersetzen %
. Dies macht den Befehl :%s/^/string/
.
-i
Switch bearbeitet die Datei nicht an Ort und Stelle. Es erstellt eine neue Datei und überschreibt die ursprüngliche, nachdem sie fertig ist (Beweis: Der Inode ändert sich). Es gibt nicht viele Tools, die tatsächlich direkt bearbeitet werden, was eine gefährliche Operation ist. Da Sie POSIX erwähnen, ist der-i
Switch für eine POSIX-kompatible Version nicht obligatorischsed
, sondern eine Funktion einiger bestimmter Implementierungen.