
Dies kann auch mit anderen Tools durchgeführt werden, mich interessiert jedoch, wie ich mit alle Zeilen außer den letzten X-Zeilen der Datei löschen kann sed
.
Antwort1
Im Grunde emulieren Sie tail. In diesem Beispiel ist x = 20. Das folgende Beispiel löscht alle Zeilen außer den letzten 20:
sed -i -e :a -e '$q;N;21,$D;ba' filename
Erläuterung:
- Mit -e :a wird eine Bezeichnung mit dem Namen a erstellt.
- Das nächste -e:
- $q - beendet und druckt den Musterbereich, wenn es die letzte Zeile ist
- N - nächste Zeile
- 21,$D – führt den Befehl „D“ aus, wenn die Zeilennummer >= 21 ist (21,$ = 21. Zeile bis $, also das Ende der Datei)
- ba – verzweigt zum Label „a“, das den Anfang des Skripts darstellt.
Antwort2
sed
ist bei Aufgaben wie dieser ziemlich komplex. tail
oder grep
würde awk
dies viel einfacher machen und sollte stattdessen verwendet werden. Davon abgesehen ist esIstmöglich.
Die folgende Lösung wurde angepasst vonsed und mehrzeiliges Suchen und Ersetzen.
sed -ni '
# if the first line copy the pattern to the hold buffer
1h
# if not the first line then append the pattern to the hold buffer
1!H
# if the last line then ...
${
# copy from the hold to the pattern buffer
g
# delete current line if it is followed by at least X more lines
# replace X-1 with the proper value
s/.*\n\(\(.*\n\)\{X-1\}\)/\1/
# print
p
}
' filename
Ohne die Kommentare ist es ein netter Einzeiler. Wenn Sie beispielsweise alles außer den letzten zehn Zeilen entfernen möchten, verwenden Sie Folgendes:
sed -ni '1h;1!H;${;g;s/.*\n\(\(.*\n\)\{9\}\)/\1/;p;}' filename
Antwort3
Basierend auf dem Skript inAbschnitt 4.13 des sed-HandbuchsSie könnten so etwas tun:
n=10
(( n > 1 )) && script='1h; 2,'$n'{H;g;}; $q; 1,'$((n-1))'d; N; D'
(( n > 1 )) || script='$!d'
sed -i "$script" infile
Antwort4
tac|sed|tac>&&(mv||Katze>)
Beide der folgenden Befehlsausschnitte löschen effektiv alle bis auf diezuletzt5Linienvon ~/file1
. Wenn Sie diezuletzt10Linien, können Sie ersetzen: |sed '1,5!d;'
durch |sed '1,10!d;'
,und so weiter, wie Sie es für richtig halten.
tac ~/"file1" |sed '1,5!d;' |tac >"/tmp/file2" &&mv "/tmp/file2" ~/"file1"
tac ~/"file1" |sed '1,5!d;' |tac >"/tmp/file2" &&cat "/tmp/file2" >~/"file1"