Voglio sapere come utilizzare grep
per visualizzare tutte le righe che iniziano e finiscono con lo stesso carattere.
Voglio sapere come utilizzare grep
per visualizzare tutte le righe che iniziano e finiscono con lo stesso carattere.
Risposte:
POSIXly:
pattern='\(.\).*\1
.'
grep -x -- "$pattern" file
Non funzionerà se la riga inizia o termina con un carattere byte non valido, se si desidera coprire quel caso, è possibile aggiungere LC_ALL=C
, anche se LC_ALL=C
funziona solo con i dati carattere a byte singolo.
perl6
sembra essere lo strumento migliore, se lo hai nella tua scatola:
$ printf '\ue7\u301 blah \u107\u327\n121\n1\n123\n' |
perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
ḉ blah ḉ
121
1
Anche se soffoca ancora su caratteri non validi.
Nota che perl6
modificherà il testo trasformandolo nella NFC
forma:
$ 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
Internamente, perl6
memorizza la stringa nella NFG
forma (acronimo di Normalization Form Grapheme
), che è il perl6
modo inventato per gestire correttamente i grafemi non precomposti:
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.chars.say'
1
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.codes.say'
2
perl6
modificherà il testo (girarlo in NFC (modulo di normalizzazione "composto")).
perl6
è store in NFG
form ( G
for Grapheme
), che è un perl6
modo per gestire correttamente i grafemi non precomposti.
Non grep ma awk:
awk -F "" 'NF && $1 == $NF'
Questi casi speciali vengono gestiti:
Un FS vuoto divide la scheda in un carattere per ogni campo gawk
, mawk
e busybox
awk
(byte, non caratteri per gli ultimi due), ma non è standard e non funziona nelle implementazioni della awk
derivata da quella originale A, W e K come su BSD e Unice commerciali. Più portatile ma più da digitare:
awk '/./ && substr($0,1,1) == substr($0,length)'
FS
come stringa vuota non è standard e non funzionerà in alcune awk
implementazioni.
awk 'length&&substr($0,1,1)==substr($0,length)'
(nota l'argomento predefinito di length
is $0
, e l'azione di default è {print $0}
)
nawk
quasi negativo :-)
grep -xe '\(.\).*\1' -e .
Esempio:
$ printf '%s\n' il y était cet été | grep -xe '\(.\).*\1' -e .
y
été
-x
è per la corrispondenza esatta (corrispondenza su tutta la riga). \1
essendo un riferimento indietro al personaggio catturato in \(.\)
. Aggiungiamo a -e .
per occuparci del caso speciale di una riga contenente un singolo carattere.
Presuppone che l'input contenga un testo valido nella locale corrente.
La corrispondenza è sul carattere , non sul byte (quelli é in UTF-8 sono i due byte 0xc3 0xa9 per esempio), né graphem cluster (non funzionerebbe se quegli é fossero scritti nella loro forma scomposta con e
seguito da U + 0301 combinando accento acuto per esempio).
Per lavorare su graphem cluster, con un grep
supporto -P
per PCRE:
$ printf 'e\u0301te\u0301\n' | grep -xPe '(\X).*\1|\X'
été
Ciò presuppone che la decomposizione sia la stessa per i due cluster, ad esempio un ḉ
espresso in quanto c
U+0301
U+0327
non corrisponderebbe a uno espresso come c
U+0327
U+0301
o ć
( U+0107
) U+0327
o ç
( U+00E7
) U+0301
o ḉ ( U+1E09
). Per questo, dovresti fare il controllo su un modulo normalizzato:
$ printf '\ue7\u301 blah \u107\u327\n' |
perl -MUnicode::Normalize -C -ne '
print if /^\X$/ || NFC($_) =~ /^(\X).*\1$/'
ḉ blah ḉ
perl6
, allora perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
dovrebbe fare tutto il lavoro per te.
Alternativa rapida a python2:
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
Esempio:
$ 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$