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

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

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

答案1

POSIXly:

pattern='\(.\).*\1
.'
grep -x -- "$pattern" file

如果行以无效字节字符开始或结束,它将不起作用,如果您想覆盖这种情况,您可以添加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

尽管它仍然因无效字符而窒息。


请注意,这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

在内部,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

答案2

不是 grep 而是 awk:

awk -F "" 'NF && $1 == $NF'

这些特殊情况的处理:

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

空 FS 将记录拆分为gawkmawk和中每个字段一个字符(字节,不是后两者的字符),但不是标准的,并且在由 A、W 和 K 等从原始记录派生的busybox awk实现中不起作用awk关于 BSD 和商业 Unices。更便携,但更容易打字:

awk '/./ && substr($0,1,1) == substr($0,length)'

答案3

grep -xe '\(.\).*\1' -e .

例子:

$ printf '%s\n' il y était cet été  | grep -xe '\(.\).*\1' -e .
y
été

-x是为了精确的匹配(整行匹配)。\1是对 中捕获的角色的反向引用\(.\)。我们添加 a-e .来处理包含单个字符的行的特殊情况。

它假设输入包含当前区域设置中的有效文本。

比赛正在进行中特点, 不是字节(例如 UTF-8 中的 é 是两个字节 0xc3 0xa9),也不是字素簇e(例如,如果这些 é 以分解形式书写,后跟 U+0301 结合尖锐的重音符号,则它将不起作用)。

要使用grep支持-PPCRE 的 graphem 集群,请执行以下操作:

$ printf 'e\u0301te\u0301\n' | grep -xPe '(\X).*\1|\X'
été

假设两个簇的分解是相同的,例如表示为的a 与表示为or ( )或( )或 ḉ ( )c U+0301 U+0327的一个不匹配。为此,您需要对规范化形式进行检查:c U+0327 U+0301ćU+0107U+0327çU+00E7U+0301U+1E09

$ printf '\ue7\u301 blah \u107\u327\n' |
  perl -MUnicode::Normalize -C -ne '
    print if /^\X$/ || NFC($_) =~ /^(\X).*\1$/'
ḉ blah ḉ

答案4

快速 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

例子:

$ 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$

相关内容