如何使用Linux在文件中搜索以相同字符开头和结尾的单词grep命令?我尝试了一些答案,但没有用。谢谢!
答案1
假设输入每行包含一个单词,您可以使用
grep -x '\(.\).*\1' file
...提取以相同字符开头和结尾的所有行。这是通过使用 捕获该行上的第一个字符\(.\)
,允许该行上的其余字符为任何内容(带有.*
),然后使用反向引用在最后强制匹配捕获的字符来完成的\1
。
选项-x
告诉grep
实用程序模式必须匹配整行,而不仅仅是该行的一部分。如果没有-x
,您将必须在正则表达式中插入显式锚点以确保匹配完整的行:^\(.\).*\1$
在我的系统字典上运行的示例,仅显示前 5 个结果:
$ grep -x '\(.\).*\1' /usr/share/dict/words | head -n 5
aa
aba
abaca
abasia
abepithymia
如果您处理的输入每行包含多个空格分隔的单词,那么您可以通过首先将其拆分为每行一个单词来预处理该文本。在这里,我另外将所有字符转换为小写,tr
同时用换行符替换空格,并通过以下方式删除重复项sort -u
:
tr ' [:upper:]' '\n[:lower:]' <file | sort -u | grep -x '\(.\).*\1'
请注意,这忽略了“普通文本”可能包含标点符号和不属于单词一部分的其他字符的事实。
在评论(现已删除)中指出,该grep
命令遗漏了单字母单词,从技术上讲,单字母单词以相同的字符开头和结尾。
要获得这些:
grep -x -e '\(.\).*\1' -e . file
现在,这将返回以相同字符开头和结尾的行或仅包含单个字符的行。
答案2
如果通过单词,你的意思是一个或多个非空白字符的任何序列,使用 GNUgrep
你可以这样做:
grep -Po '(?<!\S)(?=(\S))\S*\1(?!\S)' your-file
匹配 0 个或多个非空白字符 ( ) 的序列,这些字符以与开始处的前瞻运算符( ) 中捕获的 ( )\S*
相同的非空白字符 ( ) 结尾,使用负后视 ( ) 和两侧的前瞻 ( ) 运算符可确保找到的单词前面或后面都没有非空白字符。\1
(\S)
(?=...)
(?<!...)
(?!...)
在这个答案中,它发现:
'(?<!\S)(?=(\S))\S*\1(?!\S)'
sequences
0
that
a
它还会查找That
您是否添加该-i
选项。
答案3
使用乐(以前称为 Perl_6)
~$ raku -ne '.put if m:i/ ^ (.) .*? $0 $ /;' file
-ne
使用非自动打印命令行标志按行读取文件。 Raku 中的捕获由(
…括号表示)
,并从 开始$0
。副词的匹配不区分大小写:i
。
~$ cat /usr/share/dict/words | raku -e 'my @a; @a.push($_) if / ^ (.) .*? $0 $ / for $*IN.lines; .put for @a.elems;'
9917
(删除对上面的调用elems
以返回匹配单词的列表)。