cuo*_*glm 14
POSIXly:
pattern='\(.\).*\1
.'
grep -x -- "$pattern" file
Run Code Online (Sandbox Code Playgroud)
如果行以无效字节字符开头或结尾,它将不起作用,如果您想涵盖这种情况,您可以添加LC_ALL=C,尽管仅LC_ALL=C适用于单字节字符数据。
perl6 似乎是最好的工具,如果你有它在你的盒子里:
$ printf '\ue7\u301 blah \u107\u327\n121\n1\n123\n' |
perl6 -ne '.say if m/^(.).*$0$/ || /^.$/'
? blah ?
121
1
Run Code Online (Sandbox Code Playgroud)
尽管它仍然因无效字符而窒息。
请注意,perl6将通过将其转换为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
Run Code Online (Sandbox Code Playgroud)
在内部,perl6以NFG形式存储字符串(代表Normalization Form Grapheme),这是perl6一种正确处理未预组合字素的发明方法:
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.chars.say'
1
$ printf '\u0044\u0323\u0307\n' | perl6 -ne '.codes.say'
2
Run Code Online (Sandbox Code Playgroud)
rud*_*ier 10
不是grep而是awk:
awk -F "" 'NF && $1 == $NF'
Run Code Online (Sandbox Code Playgroud)
处理这些特殊情况:
一个空的 FS 将记录拆分为gawk,mawk和busybox awk(字节,不是后两者的字符)中的每个字段一个字符,但不是标准的,并且不适用于awkA、W 和 K 等从原始文件派生的实现在 BSD 和商业 Unices 上。更便携,但更多输入:
awk '/./ && substr($0,1,1) == substr($0,length)'
Run Code Online (Sandbox Code Playgroud)
grep -xe '\(.\).*\1' -e .
Run Code Online (Sandbox Code Playgroud)
例子:
$ printf '%s\n' il y était cet été | grep -xe '\(.\).*\1' -e .
y
été
Run Code Online (Sandbox Code Playgroud)
-x用于精确匹配(整行匹配)。\1是对 中捕获的字符的反向引用\(.\)。我们添加 a-e .来处理包含单个字符的行的特殊情况。
它假定输入包含当前语言环境中的有效文本。
匹配是在字符上,而不是字节上(例如,UTF-8 中的 é 是两个字节 0xc3 0xa9),也不是字形簇(如果这些 é 是以分解后的形式编写的,e后跟 U+0301例如结合重音)。
要使用grep支持-PPCRE 的图形集群,请执行以下操作:
$ printf 'e\u0301te\u0301\n' | grep -xPe '(\X).*\1|\X'
été
Run Code Online (Sandbox Code Playgroud)
假设两个聚类的分解相同,例如?表示为 的c U+0301 U+0327与表示为c U+0327 U+0301或?( U+0107)U+0327或ç( U+00E7)U+0301或 ? ( U+1E09). 为此,您需要对规范化形式进行检查:
$ printf '\ue7\u301 blah \u107\u327\n' |
perl -MUnicode::Normalize -C -ne '
print if /^\X$/ || NFC($_) =~ /^(\X).*\1$/'
ç? blah ??
Run Code Online (Sandbox Code Playgroud)