Saya ingin tahu cara menggunakan grep
untuk menampilkan semua baris yang dimulai dan diakhiri dengan karakter yang sama.
Saya ingin tahu cara menggunakan grep
untuk menampilkan semua baris yang dimulai dan diakhiri dengan karakter yang sama.
Jawaban:
POSIXly:
pattern='\(.\).*\1
.'
grep -x -- "$pattern" file
Ini tidak akan berfungsi jika baris dimulai atau diakhiri dengan karakter byte yang tidak valid, jika Anda ingin membahas kasus itu, Anda dapat menambahkan LC_ALL=C
, meskipun hanya LC_ALL=C
bekerja dengan data karakter byte tunggal.
perl6
tampaknya menjadi alat terbaik, jika Anda memilikinya di kotak Anda:
$ printf '\ue7\u301 blah \u107\u327\n121\n1\n123\n' |
perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
ḉ blah ḉ
121
1
Meskipun masih tersedak karakter yang tidak valid.
Catatan yang perl6
akan mengubah teks Anda dengan mengubahnya menjadi NFC
:
$ 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
Secara internal, perl6
simpan string dalam NFG
bentuk (kepanjangan Normalization Form Grapheme
), yang perl6
ditemukan cara untuk menangani grafem yang tidak dikomposisi dengan benar:
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.chars.say'
1
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.codes.say'
2
perl6
akan mengubah teks (mengubahnya menjadi NFC (bentuk normalisasi "terdiri")).
perl6
adalah store in NFG
form ( G
for Grapheme
), yang merupakan perl6
cara untuk menangani grafem yang tidak dikomposisi dengan benar.
Bukan grep tetapi awk:
awk -F "" 'NF && $1 == $NF'
Kasus-kasus khusus ini ditangani:
FS kosong membagi catatan menjadi satu karakter per bidang dalam gawk
, mawk
dan busybox
awk
(byte, bukan karakter untuk dua yang terakhir), tetapi tidak standar dan tidak bekerja dalam implementasi yang awk
diturunkan dari yang asli oleh A, W dan K seperti pada BSD dan Unives komersial. Lebih portabel tetapi lebih banyak untuk mengetik:
awk '/./ && substr($0,1,1) == substr($0,length)'
FS
string kosong tidak standar, dan tidak akan berfungsi dalam beberapa awk
implementasi.
awk 'length&&substr($0,1,1)==substr($0,length)'
(perhatikan argumen default length
adalah $0
, dan aksi default adalah {print $0}
)
nawk
yang hampir sama buruknya :-)
grep -xe '\(.\).*\1' -e .
Contoh:
$ printf '%s\n' il y était cet été | grep -xe '\(.\).*\1' -e .
y
été
-x
adalah untuk pencocokan tepat (kecocokan pada seluruh baris). \1
menjadi referensi kembali ke karakter yang ditangkap di \(.\)
. Kami menambahkan -e .
untuk menangani kasus khusus garis yang berisi satu karakter tunggal.
Itu mengasumsikan input berisi teks yang valid di lokal saat ini.
Kecocokannya adalah pada karakter , bukan byte (misalnya, é dalam UTF-8 adalah dua byte 0xc3 0xa9 misalnya), atau cluster graphem (itu tidak akan berfungsi jika é itu ditulis dalam bentuk terurai dengan e
diikuti oleh U + 0301 menggabungkan aksen akut misalnya).
Untuk bekerja pada cluster graphem, dengan grep
yang mendukung -P
PCRE:
$ printf 'e\u0301te\u0301\n' | grep -xPe '(\X).*\1|\X'
été
Itu mengasumsikan dekomposisi adalah sama untuk dua cluster, misalnya yang ḉ
dinyatakan c
U+0301
U+0327
tidak akan cocok dengan yang dinyatakan sebagai c
U+0327
U+0301
atau ć
( U+0107
) U+0327
atau ç
( U+00E7
) U+0301
atau ḉ ( U+1E09
). Untuk itu, Anda perlu melakukan pemeriksaan pada formulir yang dinormalisasi:
$ printf '\ue7\u301 blah \u107\u327\n' |
perl -MUnicode::Normalize -C -ne '
print if /^\X$/ || NFC($_) =~ /^(\X).*\1$/'
ḉ blah ḉ
perl6
, maka Anda perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
harus melakukan semua pekerjaan untuk Anda.
Alternatif python2 cepat:
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
Contoh:
$ 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$