Câu trả lời:
POSIXly:
pattern='\(.\).*\1
.'
grep -x -- "$pattern" file
Nó sẽ không hoạt động nếu dòng bắt đầu hoặc kết thúc bằng ký tự byte không hợp lệ, nếu bạn muốn bao gồm trường hợp đó, bạn có thể thêm LC_ALL=C, mặc dù chỉ LC_ALL=Choạt động với dữ liệu ký tự một byte.
perl6 dường như là công cụ tốt nhất, nếu bạn có nó trong hộp của mình:
$ printf '\ue7\u301 blah \u107\u327\n121\n1\n123\n' |
perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
ḉ blah ḉ
121
1
Mặc dù nó vẫn bóp nghẹt các ký tự không hợp lệ.
Lưu ý rằng perl6sẽ thay đổi văn bản của bạn bằng cách chuyển nó NFCthành dạng:
$ 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
Trong nội bộ, perl6lưu trữ chuỗi NFGdưới dạng (viết tắt Normalization Form Grapheme), đây là perl6cách được phát minh để đối phó với các biểu đồ chưa được phân tách đúng cách:
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.chars.say'
1
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.codes.say'
2
perl6sẽ thay đổi văn bản mặc dù (chuyển nó thành NFC (dạng chuẩn hóa "sáng tác")).
perl6được lưu trữ ở NFGdạng ( Gfor Grapheme), đó là perl6cách để đối phó với các biểu đồ không được phân tách đúng.
Không phải grep mà là awk:
awk -F "" 'NF && $1 == $NF'
Những trường hợp đặc biệt được xử lý:
Một FS trống chia các bản ghi vào một ký tự cho mỗi lĩnh vực trong gawk, mawkvà busybox awk(byte, không ký tự cho sau này hai), nhưng không phải là tiêu chuẩn và không làm việc trong hiện thực của awknguồn gốc từ một bản gốc bằng A, W và K như trên BSD và các đơn vị thương mại. Di động hơn nhưng nhiều hơn để gõ:
awk '/./ && substr($0,1,1) == substr($0,length)'
FSvì chuỗi rỗng không phải là tiêu chuẩn và sẽ không hoạt động trong một số awktriển khai.
awk 'length&&substr($0,1,1)==substr($0,length)'(lưu ý đối số mặc định của lengthlà $0, và hành động mặc định là {print $0})
nawkgần như tồi tệ :-)
grep -xe '\(.\).*\1' -e .
Thí dụ:
$ printf '%s\n' il y était cet été | grep -xe '\(.\).*\1' -e .
y
été
-xlà cho trận đấu chính xác (trận đấu trên toàn bộ dòng). \1là một tài liệu tham khảo ngược cho nhân vật bị bắt trong \(.\). Chúng tôi thêm một -e .để chăm sóc trường hợp đặc biệt của một dòng chứa một ký tự đơn.
Nó giả sử đầu vào chứa văn bản hợp lệ trong ngôn ngữ hiện tại.
Trận đấu diễn ra trên ký tự , không phải byte (ví dụ, trong é trong UTF-8 là hai byte 0xc3 0xa9 chẳng hạn), cũng không phải cụm graphem (nó sẽ không hoạt động nếu những é đó được viết ở dạng phân tách của chúng etheo sau là U + 0301 kết hợp giọng cấp tính chẳng hạn).
Để làm việc trên các cụm đồ thị, với một grephỗ trợ -Pcho PCRE:
$ printf 'e\u0301te\u0301\n' | grep -xPe '(\X).*\1|\X'
été
Giả định rằng sự phân tách là giống nhau cho hai cụm, ví dụ, một ḉbiểu thức c U+0301 U+0327sẽ không khớp với một biểu thức là c U+0327 U+0301hoặc ć( U+0107) U+0327hoặc ç( U+00E7) U+0301hoặc ( U+1E09). Vì vậy, bạn cần thực hiện kiểm tra trên một biểu mẫu chuẩn hóa:
$ printf '\ue7\u301 blah \u107\u327\n' |
perl -MUnicode::Normalize -C -ne '
print if /^\X$/ || NFC($_) =~ /^(\X).*\1$/'
ḉ blah ḉ
perl6, sau đó perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'nên làm tất cả các công việc cho bạn.
Thay thế nhanh 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
Thí dụ:
$ 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$