Saya ingin tahu cara menggunakan grepuntuk menampilkan semua baris yang dimulai dan diakhiri dengan karakter yang sama.
Saya ingin tahu cara menggunakan grepuntuk 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=Cbekerja 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 perl6akan 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, perl6simpan string dalam NFGbentuk (kepanjangan Normalization Form Grapheme), yang perl6ditemukan 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
perl6akan mengubah teks (mengubahnya menjadi NFC (bentuk normalisasi "terdiri")).
perl6adalah store in NFGform ( Gfor Grapheme), yang merupakan perl6cara 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, mawkdan busybox awk(byte, bukan karakter untuk dua yang terakhir), tetapi tidak standar dan tidak bekerja dalam implementasi yang awkditurunkan 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)'
FSstring kosong tidak standar, dan tidak akan berfungsi dalam beberapa awkimplementasi.
awk 'length&&substr($0,1,1)==substr($0,length)'(perhatikan argumen default lengthadalah $0, dan aksi default adalah {print $0})
nawkyang hampir sama buruknya :-)
grep -xe '\(.\).*\1' -e .
Contoh:
$ printf '%s\n' il y était cet été | grep -xe '\(.\).*\1' -e .
y
été
-xadalah untuk pencocokan tepat (kecocokan pada seluruh baris). \1menjadi 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 ediikuti oleh U + 0301 menggabungkan aksen akut misalnya).
Untuk bekerja pada cluster graphem, dengan grepyang mendukung -PPCRE:
$ 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+0327tidak akan cocok dengan yang dinyatakan sebagai c U+0327 U+0301atau ć( U+0107) U+0327atau ç( U+00E7) U+0301atau ḉ ( 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$