Ich möchte einige n Zeilen vom Ende einer Datei entfernen. Kann das mit sed gemacht werden?
Um beispielsweise Zeilen von 2 bis 4 zu entfernen, kann ich verwenden
$ sed '2,4d' file
Aber ich kenne die Zeilennummern nicht. Ich kann die letzte Zeile mit löschen
$sed $d file
aber ich möchte wissen, wie man n Zeilen vom Ende entfernt. Bitte lassen Sie mich wissen, wie ich das mit sed oder einer anderen Methode tun kann.
Ich weiß nichts von sed
, aber es kann mit head
gemacht werden
head -n -2 myfile.txt
Wenn Hardcoding n eine Option ist, können Sie sequenzielle Aufrufe von sed verwenden. Um beispielsweise die letzten drei Zeilen zu löschen, löschen Sie die letzte Zeile dreimal:
sed '$d' file | sed '$d' | sed '$d'
Aus den sed Einlinern :
# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2
Scheint das zu sein, wonach du suchst.
Eine lustige und einfache sed
- und tac
-Lösung:
n=4
tac file.txt | sed "1,$n{d}" | tac
HINWEIS
"
werden benötigt, damit die Shell die $n
-Variable im Befehl sed
auswertet. In einfachen Anführungszeichen wird keine Interpolation ausgeführt.tac
ist eine cat
umgekehrt, siehe man 1 tac
{}
in sed
sind da, um $n
& d
zu trennen (andernfalls versucht die Shell, die nicht vorhandene $nd
-Variable zu interpolieren)Verwenden Sie sed
, aber lassen Sie die Shell die Berechnungen ausführen, mit dem Ziel, den Befehl d
zu verwenden, indem Sie einen Bereich angeben (um die letzten 23 Zeilen zu entfernen):
sed -i "$(($(wc -l < file)-22)),\$d" file
Um die letzten 3 Zeilen von innen nach außen zu entfernen:
$(wc -l < file)
Gibt die Anzahl der Zeilen der Datei an: say 2196
Wir möchten die letzten 23 Zeilen entfernen, also für die linke Seite oder den Bereich:
$((2196-22))
Ergibt: 2174 Die ursprüngliche Sedierung nach Shell-Interpretation lautet also:
sed -i 2174,$d file
Mit -i
beim Inplace-Editieren ist die Datei jetzt 2173 lines!
Sie könnten head dafür verwenden.
Benutzen
$ head --lines=-N file > new_file
dabei ist N die Anzahl der Zeilen, die Sie aus der Datei entfernen möchten.
Der Inhalt der Originaldatei minus den letzten N Zeilen befindet sich jetzt in new_file
Der Vollständigkeit halber möchte ich meine Lösung hinzufügen. __ Ich habe dies mit dem Standard ed
getan:
ed -s sometextfile <<< $'-2,$d\nwq'
Dies löscht die letzten 2 Zeilen durch In-Place-Bearbeitung (obwohl tut eine temporäre Datei in /tmp
!! verwendet).
Um sehr große Dateien wirklich direkt abschneiden zu können, haben wir truncate
befehl . Es kennt keine Zeilen, aber tail
+ wc
kann Zeilen in Bytes konvertieren:
file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file
Wenn die Datei gleichzeitig geschrieben wird, liegt eine offensichtliche Race-Bedingung vor. In diesem Fall ist es möglicherweise besser, head
zu verwenden - sie zählt Bytes vom Anfang der Datei (Mind-Disk-IO) Zeilenumrandung (möglicherweise mehr Zeilen als erwartet, wenn Datei aktiv geschrieben wird):
truncate -s $(head -n -$lines $file | wc -c) $file
Praktischer One-Liner, wenn der Login-Versuch fehlschlägt, anstelle des Benutzernamens ein Kennwort einzugeben:
truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure
Das könnte für Sie funktionieren (GNU sed):
sed ':a;$!N;1,4ba;P;$d;D' file
Die meisten der obigen Antworten scheinen GNU Befehle/Erweiterungen zu erfordern:
$ head -n -2 myfile.txt
-2: Badly formed number
Für eine etwas mehr tragbare Lösung:
Perl -ne 'Push(@fifo,$_);print shift(@fifo) if @fifo > 10;'
OR
Perl -ne 'Push(@buf,$_);END{print @buf[0 ... $#buf-10]}'
OR
awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'
Wo "10" ist "n".
Mit den Antworten hier haben Sie bereits gelernt, dass sed nicht das beste Werkzeug für diese Anwendung ist.
Ich denke jedoch, dass es einen Weg gibt, dies mit sed zu tun; Die Idee ist, N Zeilen anzufügen, um Platz zu halten, bis Sie lesen können, ohne EOF zu treffen. Wenn EOF gedrückt wird, drucken Sie den Inhalt des Speicherbereichs und beenden Sie den Vorgang.
sed -e '$!{N;N;N;N;N;N;H;}' -e x
Mit dem obigen Befehl sed werden die letzten 5 Zeilen weggelassen.
Versuchen Sie den folgenden Befehl:
n = line number
tail -r file_name | sed '1,nd' | tail -r
Dies kann in 3 Schritten erfolgen:
a) Zählen Sie die Anzahl der Zeilen in der Datei, die Sie bearbeiten möchten:
n=`cat myfile |wc -l`
b) Ziehen Sie von dieser Anzahl die Anzahl der zu löschenden Zeilen ab:
x=$((n-3))
c) Verweisen Sie sed, diese Zeile ($x
) bis zum Ende zu löschen:
sed "$x,\$d" myfile
Sie können die Gesamtzahl der Zeilen mit wc -l <file>
abrufen und verwenden
head -n <total lines - lines to remove> <file>
Dadurch werden die letzten 12 Zeilen entfernt
sed -n -e :a -e '1,10!{P;N;D;};N;ba'
So löschen Sie die letzten 4 Zeilen:
$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*\t//'
sed -n ':pre
1,4 {N;b pre
}
:cycle
$!{P;N;D;b cycle
}' YourFile
posix-Version
Dadurch werden die letzten 3 Zeilen aus file
entfernt:
for i in $(seq 1 3); do sed -i '$d' file; done;
Ich habe mir das ausgedacht, wobei n die Anzahl der Zeilen ist, die Sie löschen möchten:
count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt
Es ist ein kleiner Kreisverkehr, aber ich denke, es ist leicht zu folgen.
Um die letzten N Zeilen einer Datei zu löschen, können Sie das gleiche Konzept von verwenden
$ sed '2,4d' file
Sie können eine Kombination mit dem Befehl tail verwenden, um die Datei umzukehren: wenn N 5 ist
$ tail -r file | sed '1,5d' file | tail -r > file
Und dieser Weg läuft auch dort, wo der Befehl head -n -5 file
nicht läuft (wie auf einem Mac!).
Ich bevorzuge diese Lösung.
head -$(gcalctool -s $(cat file | wc -l)-N) file
dabei istNdie Anzahl der zu entfernenden Zeilen.