Wie lösche ich alle Zeilen in einer Textdatei, die weniger als „x“ Zeichen haben?

Wie lösche ich alle Zeilen in einer Textdatei, die weniger als „x“ Zeichen haben?

Wie kann ich alle Zeilen in einer Textdatei löschen, die weniger als „x“ Buchstaben ODER Zahlen ODER Symbole enthalten? Ich kann es nicht verwenden, awk 'length($0)>'da es Leerzeichen enthalten würde.

Antwort1

Angenommen, Sie möchten Zeilen löschen, die weniger als ngrafische Symbole enthalten:

awk -v n=5 '{ line = $0; gsub("[^[:graph:]]", "") } length >= n { print line }'

Dadurch werden alle Zeichen gelöscht, die nicht übereinstimmen [[:graph:]]. Wenn die Länge der verbleibenden Zeichenfolge größer oder gleich ist n, wird die (unveränderte) Zeile gedruckt.

Der Wert nwird in der Befehlszeile angegeben.

[[:graph:]]ist gleichwertig mit [[:alnum:][:punct:]], was wiederum dasselbe ist wie [[:alpha:][:digit:][:punct:]]. Es ist ungefähr dasselbe wie , [[:print:]]stimmt aber nicht mit Leerzeichen überein.

Anstelle von [^[:graph:]]können Sie möglicherweise auch verwenden, [[:blank:]]um alle Tabs oder Leerzeichen zu löschen.

Mit sed, indem Sie den obigen awkCode fast wörtlich befolgen,

sed -e 'h; s/[^[:graph:]]//g' \
    -e '/.\{5\}/!d; g'

oder, vereinfacht (nur Zeichen zählen, die keine Leerzeichen sind),

sed -e 'h; s/[[:blank:]]//g' \
    -e '/...../!d; g'

Dies speichert zuerst die aktuelle Zeile mit in den Haltebereich h. Anschließend werden alle Nicht-Graphzeichen (oder Leerzeichen in der zweiten Variante) in der Zeile mit gelöscht s///g. Wenn die Zeile dann weniger als 5 Zeichen enthält (ändern Sie dies in eine beliebige Zahl oder ändern Sie die Anzahl der Punkte in der zweiten Variante), wird die Zeile gelöscht. Andernfalls wird die gespeicherte Zeile mit aus dem Haltebereich geholt gund (implizit) gedruckt.

Antwort2

sed -e 's/[^[:space:][:cntrl:]]/&/20' -e t -e d < file

würde die Zeilen von drucken, filedie mindestens 20 Zeichen enthalten, die keine Leerzeichen und keine Steuerzeichen sind (siehe auch [[:graph:]]oder [[:alnum:][:punct:]], es ist nicht klar, welche Zeichen Sie in Ihre Beschreibung einschließen bzw. ausschließen möchten; beachten Sie, dass auf einigen Systemen das geschützte Leerzeichen in enthalten ist graphund nicht in space).

Die Idee besteht darin, dass versucht wird, das 20. Vorkommen eines Zeichens, das kein Leerzeichen/Steuerzeichen ist, durch sich selbst zu ersetzen ( &). Wenn diese Ersetzung erfolgreich ist, verzweigen wir ( t) und überspringen so die dAktion (Löschen).

Mit awkkönnen Sie Folgendes tun:

awk 'gsub(/[^[:space:][:cntrl:]]/, "&") >= 20' < file

Verlassen Sie sich auf die Tatsache, dass gsub()die Anzahl der vorgenommenen Ersetzungen zurückgegeben wird.

Mit grep:

grep -E '^([[:space:][:cntrl:]]*[^[:space:][:cntrl:]]){20}' <  file

( (.*[^[:space:][:cntrl:]]){20}würde auch gehen, wäre aber teurer).

Antwort3

Dadurch werden die Zeilen gelöscht, die 10 und weniger als 10 Zeichen enthalten:

sed -E '/^.{1,11}$/d' filename

ODER

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

Wenn Sie Leerzeichen kürzen möchten, können Sie Folgendes verwenden:

sed -E 's/^[[:space:]]*//g;s/[[:space:]]*$//g;/^.{1,11}$/d' filename

Wenn Sie direkt in der Datei löschen möchten, verwenden Sie-ichOption damit.

Antwort4

Verwendung von Raku (geb. Perl6)

raku -ne '.put if chars( S:g/\s// ) >= 10;'  filename

oder

raku -ne '.put unless chars( S:g/\s// ) < 10;'  filename

oder

raku -ne '.put unless chars( S:g/\W// ) < 10;'  filename

oder

raku -ne '.put unless chars( S:g/<ws>// ) < 10;'  filename

Kurz gesagt wird in Raku/Perl6 der Operator „großes S“ S///verwendet, um eine resultierende Zeichenfolge ohne unerwünschte Zeichen (z. B. Leerzeichen) zu generieren. Die Zeichen der resultierenden Zeichenfolge werden mit der charsFunktion gezählt, mit „n“ verglichen (am Beispiel von 10) und schließlich – wenn der Boolesche Wert erfüllt ist – .putwird die ursprüngliche Zeile unverändert zurückgegeben.

Anmerkung 1: „S/// verwendet die gleiche Semantik wie der Operator s///, außer dass es die ursprüngliche Zeichenfolge unverändert lässt und die resultierende Zeichenfolge anstelle von $/ zurückgibt ($/ wird immer noch auf die gleichen Werte wie bei s/// gesetzt).“

https://docs.raku.org/language/regexes#S///_non-destructive_substitution

Hinweis 2: In Raku/Perl6 werden Regex-Modifikatoren wie (für „global“) als Adverbien bezeichnet und (normalerweise) am Anfang des „ oder“ -Operators direkt nach dem „oder“ :gplatziert .S///s///Ss

Hinweis 3: Der .Punkt in Raku/Perl6 wird verwendet, um eine Methode für die Themenvariable aufzurufen $_, daher ist das erste „Wort“ des Codes .putim Wesentlichen eine Abkürzung für $_.put.

https://docs.raku.org/language/5to6-nutshell#-%3E_Method_calls

Hinweis 4: Raku/Perl6 hat einen viel eingeschränkteren Satz von Befehlszeilenflags. Das -eFlag („execute“) führt Raku/Perl6-Code in der Befehlszeile aus. Das -nFlag führt den Raku/Perl6-Code zeilenweise aus, d. h. für jede Zeile einer Eingabedatei eine Zeile nach der anderen, und gibt ein Ergebnis zurück. Die beiden Flags können zu einem -neFlag kombiniert werden, aber unabhängig davon muss das -eFlag zuletzt kommen.

Perl_6-Links:
https://docs.raku.org/language/5to6-nutshell#Command-line_flags
https://github.com/rakudo/rakudo/wiki/Running-rakudo-from-the-command-line

verwandte Informationen