Antworten:
Das kannst du nicht. Verwenden Sie entweder ed oder GNU sed oder perl oder tun Sie das, was Sie hinter den Kulissen tun: Erstellen Sie eine neue Datei für den Inhalt.
ed
, tragbar:
ed foo <<EOF
1,$s/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/
w
q
EOF
GNU sed
:
sed -i -e 's/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/' foo
Perl:
perl -i -l -F, -pae 'print @F[1,3]' foo
cut
, Erstellen einer neuen Datei (empfohlen, da Sie Ihr Skript bei einer Unterbrechung einfach erneut ausführen können):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut
, Ersetzen der Datei an Ort und Stelle (behält das Eigentum und die Berechtigungen von foo
, muss aber vor Unterbrechungen geschützt werden):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
Ich empfehle eine der cut
-basierten Methoden. Auf diese Weise sind Sie nicht auf ein nicht standardmäßiges Tool angewiesen. Sie können das beste Tool für den Job verwenden und das Verhalten bei Unterbrechungen steuern.
cut -d , -f 1,3 foo > foo.new
rm foo
mv foo.new foo
rm foo
. Und Sie sollten nicht anrufen rm foo
, weil mv foo.new foo
es atomar ist: Es entfernt die alte Version und setzt gleichzeitig die neue Version ein.
Das moreutils- Paket von Ubuntu (und auch Debian ) hat ein Programm sponge
, das sozusagen auch Ihr Problem löst.
Vom mann schwamm:
Schwamm liest die Standardeingabe und schreibt sie in die angegebene Datei. Im Gegensatz zu einer Shell-Umleitung nimmt der Schwamm alle Eingaben auf, bevor die Ausgabedatei geöffnet wird. Auf diese Weise können Pipelines eingeschränkt werden, die aus derselben Datei lesen und in dieselbe Datei schreiben.
Welches würde Sie etwas tun lassen wie:
cut -d <delim> -f <fields> somefile | sponge somefile
Ich denke nicht, dass das cut
alleine möglich ist . Ich konnte es auf der Man- oder Infoseite nicht finden. Sie können so etwas tun wie
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktemp
macht Sie zu einer relativ sicheren temporären Datei, in die Sie die cut
Ausgabe umleiten können.
Sie können slurp mit POSIX Awk verwenden:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Nun, da es cut
weniger ausgibt als es liest, können Sie Folgendes tun:
cut -c1 < file 1<> file
Dies bedeutet, dass die Standardeingabe file
im schreibgeschützten Modus und die Standardeingabe file
im schreibgeschützten Modus ohne Kürzung ( <>
) geöffnet wird .
Auf diese Weise cut
wird nur die Datei über sich selbst überschrieben. Der Rest der Datei bleibt jedoch unberührt. Zum Beispiel, wenn file
enthält:
foo
bar
Die Ausgabe wird zu:
f
b
bar
Die f\nb\n
haben ersetzt foo\n
, sind aber bar
noch da. Sie müssen die Datei nach cut
Abschluss abschneiden .
Mit ksh93
können Sie dies mit dem <>;
Operator tun, der sich so <>
verhält, als ob bei erfolgreichem Befehl ftruncate()
der Dateideskriptor aufgerufen wird. So:
cut -c1 < file 1<>; file
Bei anderen Shells müssten Sie das auf ftruncate()
anderem Wege tun , wie zum Beispiel:
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
perl
Nur dafür aufzurufen , ist hier allerdings etwas übertrieben, vor allem, wenn man bedenkt, dass perl
dies leicht gelingen kann cut
wie:
perl -pi -e '$_ = substr($_, 0, 1)' file
Beachten Sie, dass bei allen Methoden, die ein tatsächliches Umschreiben vor Ort beinhalten, eine beschädigte Datei angezeigt wird, wenn der Vorgang auf halbem Weg unterbrochen wird. Die Verwendung einer temporären zweiten Datei vermeidet dieses Problem.
.old
Methode für Änderungen an Ort und Stelle,echo "$(cut -d , -f 1,3 <foo)" > foo