it-swarm.com.de

Verwendung von sed zum Entfernen der letzten n Zeilen einer Datei

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.

109
mezda

Ich weiß nichts von sed, aber es kann mit head gemacht werden

head -n -2 myfile.txt
180
ams

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'
24
Kyle

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.

22
qstebom

Eine lustige und einfache sed- und tac-Lösung:

n=4
tac file.txt | sed "1,$n{d}" | tac

HINWEIS

  • doppelte Anführungszeichen " 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
  • die {} in sed sind da, um $n & d zu trennen (andernfalls versucht die Shell, die nicht vorhandene $nd-Variable zu interpolieren)
20
Gilles Quenot

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!

13
lzc

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

10
richard

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).

7
Michel

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
5
Kamil Christ

Das könnte für Sie funktionieren (GNU sed):

sed ':a;$!N;1,4ba;P;$d;D' file
4
potong

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".

2
DarkHeart

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.

2
Rishabh Sagar

Versuchen Sie den folgenden Befehl:

n = line number
tail -r file_name | sed '1,nd' | tail -r
2
Rishav Kaushal

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
1
Rey Lefebvre

Sie können die Gesamtzahl der Zeilen mit wc -l <file> abrufen und verwenden

head -n <total lines - lines to remove> <file>

1
SWW13

Dadurch werden die letzten 12 Zeilen entfernt

sed -n -e :a -e '1,10!{P;N;D;};N;ba'
0
R. Kumar

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//'   
0
mstafreshi
sed -n ':pre
1,4 {N;b pre
    }
:cycle
$!{P;N;D;b cycle
  }' YourFile

posix-Version

0
NeronLeVelu

Dadurch werden die letzten 3 Zeilen aus file entfernt:

for i in $(seq 1 3); do sed -i '$d' file; done;

0
user5780554

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.

  1. Zählen Sie die Anzahl der Zeilen in der Hauptdatei hoch
  2. Subtrahieren Sie die Anzahl der Zeilen, die Sie von der Zählung entfernen möchten
  3. Drucken Sie die Anzahl der Zeilen aus, die Sie behalten möchten, und speichern Sie sie in einer temporären Datei
  4. Ersetzen Sie die Hauptdatei durch die temporäre Datei
  5. Entfernen Sie die temporäre Datei
0
coyotetechy

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!).

0

Ich bevorzuge diese Lösung.

head -$(gcalctool -s $(cat file | wc -l)-N) file

dabei istNdie Anzahl der zu entfernenden Zeilen.

0
p014k