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 n
grafische 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 n
wird 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 awk
Code 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 g
und (implizit) gedruckt.
Antwort2
sed -e 's/[^[:space:][:cntrl:]]/&/20' -e t -e d < file
würde die Zeilen von drucken, file
die 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 graph
und 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 d
Aktion (Löschen).
Mit awk
kö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 chars
Funktion gezählt, mit „n“ verglichen (am Beispiel von 10) und schließlich – wenn der Boolesche Wert erfüllt ist – .put
wird 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“ :g
platziert .S///
s///
S
s
Hinweis 3: Der .
Punkt in Raku/Perl6 wird verwendet, um eine Methode für die Themenvariable aufzurufen $_
, daher ist das erste „Wort“ des Codes .put
im 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 -e
Flag („execute“) führt Raku/Perl6-Code in der Befehlszeile aus. Das -n
Flag 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 -ne
Flag kombiniert werden, aber unabhängig davon muss das -e
Flag 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