Ich möchte wissen, wie man verwendet grep, um alle Zeilen anzuzeigen, die mit demselben Zeichen beginnen und enden.
Ich möchte wissen, wie man verwendet grep, um alle Zeilen anzuzeigen, die mit demselben Zeichen beginnen und enden.
Antworten:
POSIXly:
pattern='\(.\).*\1
.'
grep -x -- "$pattern" file
Es funktioniert nicht, wenn die Zeile mit einem ungültigen Bytezeichen beginnt oder endet. Wenn Sie diesen Fall abdecken möchten, können Sie hinzufügen LC_ALL=C, obwohl dies nur LC_ALL=Cmit Einzelbyte-Zeichendaten funktioniert.
perl6 scheint das beste Werkzeug zu sein, wenn Sie es in Ihrer Box haben:
$ printf '\ue7\u301 blah \u107\u327\n121\n1\n123\n' |
perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
ḉ blah ḉ
121
1
Obwohl es immer noch an ungültigen Zeichen erstickt.
Beachten Sie, dass perl6sich Ihr Text ändert, indem Sie ihn in eine NFCForm verwandeln :
$ printf '\u0044\u0323\u0307\n' |
perl6 -pe '' |
perl -CI -ne 'printf "U+%04x\n", ord for split //'
U+1e0c
U+0307
U+000a
$ printf '\u0044\u0323\u0307\n' |
perl -pe '' |
perl -CI -ne 'printf "U+%04x\n", ord for split //'
U+0044
U+0323
U+0307
U+000a
Intern perl6speichert Zeichenfolge in NFGForm (steht für Normalization Form Grapheme), die perl6erfunden wurde, um mit nicht vorkomponierten Graphemen richtig umzugehen:
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.chars.say'
1
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.codes.say'
2
perl6der Text dadurch geändert wird (drehen Sie ihn in NFC (Normalisierungsformular "zusammengesetzt")).
perl6in NFGForm ( Gfür Grapheme) gespeichert wird perl6, um mit nicht vorkomponierten Graphemen richtig umzugehen.
Nicht grep aber awk:
awk -F "" 'NF && $1 == $NF'
Diese Sonderfälle werden behandelt:
Ein leerer FS teilt den Datensatz in ein Zeichen pro Feld gawk, mawkund busybox awk(Bytes, keine Zeichen für die letzteren zwei), ist aber nicht Standard und funktioniert nicht in den Implementierungen der awkvon der ursprünglichen , abgeleitet durch A, W und K wie auf BSDs und kommerziellen Einheiten. Tragbarer, aber mehr zu tippen:
awk '/./ && substr($0,1,1) == substr($0,length)'
FSeine leere Zeichenfolge kein Standard ist und in einigen awkImplementierungen nicht funktioniert .
awk 'length&&substr($0,1,1)==substr($0,length)'(Standardargument von lengthis beachten $0und Standardaktion ist {print $0})
nawkdie fast genauso schlecht ist :-)
grep -xe '\(.\).*\1' -e .
Beispiel:
$ printf '%s\n' il y était cet été | grep -xe '\(.\).*\1' -e .
y
été
-xist für die genaue Übereinstimmung (Übereinstimmung auf der gesamten Linie). \1als Rückverweis auf den in \(.\). Wir fügen ein hinzu -e ., um den Sonderfall einer Zeile mit einem einzelnen Zeichen zu behandeln.
Es wird davon ausgegangen, dass die Eingabe gültigen Text im aktuellen Gebietsschema enthält.
Das Spiel ist auf Zeichen , nicht - Byte (die é in UTF-8 sind die zwei Bytes 0xC3 0xA9 zum Beispiel), noch Graphem - Cluster (es würde nicht funktionieren , wenn diejenigen E wurden in ihrem zerlegten Form geschrieben mit egefolgt von der U + 0301 zum Beispiel akuten Akzent kombinieren).
So arbeiten Sie an Graphemclustern mit einem grep, der -PPCRE unterstützt :
$ printf 'e\u0301te\u0301\n' | grep -xPe '(\X).*\1|\X'
été
Dies setzt voraus, dass die Zerlegung für die beiden Cluster gleich ist, zum Beispiel ein ḉAusdruck, c U+0301 U+0327der nicht mit einem übereinstimmt, der als c U+0327 U+0301oder ć( U+0107) U+0327oder ç( U+00E7) U+0301oder ḉ ( U+1E09) ausgedrückt wird . Dazu müssten Sie die Prüfung auf einem normalisierten Formular durchführen:
$ printf '\ue7\u301 blah \u107\u327\n' |
perl -MUnicode::Normalize -C -ne '
print if /^\X$/ || NFC($_) =~ /^(\X).*\1$/'
ḉ blah ḉ
perl6, dann perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'sollten Sie alle Arbeiten für Sie erledigen.
Schnelle Python2-Alternative:
python -c 'import sys;[sys.stdout.write(l) for l in sys.stdin if len(l)>1 and l.rstrip("\n").endswith(l[0])]' < input.txt
Beispiel:
$ python -c 'import sys;[sys.stdout.write(l) for l in sys.stdin if len(l)>1 and l.rstrip("\n").endswith(l[0])]' < input.txt | cat -A
nathan$
ookie $
a line a$