grep 命令显示所有以相同字符开头和结尾的行

Nay*_*ala 8 grep text-processing

我想知道如何使用grep以显示以相同字符开头和结尾的所有行。

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)

在内部,perl6NFG形式存储字符串(代表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)

  • Perl 对 Unicode 文本的处理堪称典范,以至于 Perl 中的许多“简单”任务实际上无法使用其他工具来实现,至少在相同级别的正确性下是不可能的。 (2认同)

rud*_*ier 10

不是grep而是awk:

awk -F "" 'NF && $1 == $NF'
Run Code Online (Sandbox Code Playgroud)

处理这些特殊情况:

  • 它不打印空行
  • 它总是打印 1 个字符的行

一个空的 FS 将记录拆分为gawk,mawkbusybox awk(字节,不是后两者的字符)中的每个字段一个字符,但不是标准的,并且不适用于awkA、W 和 K 等从原始文件派生的实现在 BSD 和商业 Unices 上。更便携,但更多输入:

awk '/./ && substr($0,1,1) == substr($0,length)'
Run Code Online (Sandbox Code Playgroud)

  • 避免拆分并且完全可移植的替代方案(即使对于最糟糕的 Solaris '旧' awk)`awk 'length&&substr($0,1,1)==substr($0,length)'`(注意 `length` 的默认参数是`$0`,默认操作是 `{print $0}`) (2认同)

Sté*_*las 8

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)