Wie entferne ich Linien, die kürzer als XY sind?

29

Ich habe eine Frage gefunden, wie man Zeilen mit einer Länge von mehr als 2048 Zeichen entfernt:

Wie lösche ich eine Zeile, die länger als XY ist?

F: Aber wie kann ich Zeilen entfernen, die kürzer als 4 Zeichen sind? Entfernen Sie also Zeilen mit einer Länge von 1, 2 oder 3 in einer Datei.

UPDATE: Danke für die vielen GUTEN Antworten, aber ich kann nur eine als OK markieren

evachristine
quelle

Antworten:

42

Du könntest es gebrauchen sed. Das Folgende würde Zeilen entfernen, die 3 Zeichen lang oder kleiner sind:

sed -r '/^.{,3}$/d' filename

Geben Sie die -iOption an, um die Änderungen an der Datei direkt zu speichern .

Wenn Ihre Version von seddie erweiterte RE-Syntax nicht unterstützt, können Sie dasselbe in BRE schreiben:

sed '/^.\{,3\}$/d' filename

was mit allen sedvarianten klappen würde.


Sie könnten auch verwenden awk:

awk 'length($0)>3' filename

Verwenden von perl:

perl -lne 'length()>3 && print' filename
devnull
quelle
sed '/^.\{,3\}$/d'nicht mit BSD arbeiten sed: sed: 1: "/^.\{,3\}$/d": RE error: invalid repetition count(s). Die sed -r-Version ist syntaktisch gültig, entfernt jedoch keine Zeilen.
Dereckson
5

Einige weitere Variationen:

grep .... file

oder

sed '/..../!d' file

oder

sed -n 's/./&/4p' file

oder

awk 'gsub(/./,"&")>3' file

oder

awk 'length>3' file

oder GNU awk:

awk 'NF>3' FS= file
Scrutinizer
quelle
1
Oh das grep .... ist so elegant!
Freitag,
3

Hier ist die Vim-Lösung, die den Vim-Ex-Modus und den globalBefehl verwendet.

Dies ist der Verwendung von sehr ähnlich sed, nur dass einige Sonderzeichen ('{', '}') maskiert werden müssen.

:g/^.\{,3\}$/d

Mit Vims Very Magic Regex-Modus (\ v) kann dieses Entkommen vermieden werden.

:g/\v^.{,3}$/d

Siehe auch: Hilf der Magie

Use of "\v" means that in the pattern after it all ASCII characters except
'0'-'9', 'a'-'z', 'A'-'Z' and '_' have a special meaning.  "very magic"

Manchmal ist es auch nützlich, das Gegenteil zu tun vglobal.

:v/\v^.{,3}$/d

würde bis auf 3 Zeichen alles außer Zeilen löschen.

gergap
quelle
1

Um die Zeilen direkt zu entfernen, können Sie:

sed -ri '/.{4}/!d' /path/to/file

Oder BRE:

sed -i '/.\{4\}/!d' /path/to/file

Wenn eine Zeile nicht aus 4 oder mehr Zeichen besteht, wird sie gelöscht.

f=/path/to/file
cat <<GREP >"$f"
    $(grep -E ".{4}" "$f")
GREP

Wenn Sie in der Befehlsersetzungs-Subshell das Obige ausführen, wird sichergestellt, dass grepein Lesedeskriptor angezeigt wird, bevor cat mit dem Schreiben beginnt. <<HEREDOCAußerdem wird dadurch sichergestellt, dass das Ergebnis gestreamt bleibt und keine Argumentlängenfehler verursacht.

mikeserv
quelle
0
sed '/^.\?.\?.\?$/d' input.txt > output.txt
Hauke ​​Laging
quelle
0

Sie können verwenden grep:

Wenn Sie führende Leerzeichen in der Zeilenlänge zählen:

grep -e '[^\ ]\{4,\}' file

Wenn Sie in der Zeilenlänge keine führenden Leerzeichen zählen:

grep -e '[^\]\{4,\}' file
cuonglm
quelle