Can grep show only words that match search pattern?
有没有办法让grep从与搜索表达式匹配的文件中输出"words"?
如果我想在多个文件中找到"th"的所有实例,可以这样做:
1 | grep"th" * |
但是输出将是类似的(粗体由我决定);
1 2 3 | some-text-file : the cat sat on the mat some-other-text-file : the quick brown fox yet-another-text-file : i hope this explains it thoroughly |
我希望它使用相同的搜索输出:
1 2 3 4 5 | the the the this thoroughly |
是否可以使用grep?或者使用其他工具组合?
尝试GRPO
1 | grep -oh"\w*th\w*" * |
编辑:与菲尔的评论匹配
来自文档:
1 2 3 4 5 6 | -h, --no-filename Suppress the prefixing of file names on output. This is the default when there is only one file (or only standard input) to search. -o, --only-matching Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line. |
交叉分发安全答案(包括Windows Mingw?)
1 2 | grep -h"[[:alpha:]]*th[[:alpha:]]*" 'filename' | tr ' ' ' ' | grep -h"[[:alpha:]]*th[[:alpha:]]*" |
如果您使用不包含-o选项的grep的旧版本(如2.4.2)。使用上述内容。否则使用下面的简单维护版本。
Linux交叉分发安全答案
1 | grep -oh"[[:alpha:]]*th[[:alpha:]]*" 'filename' |
为了总结
更多关于grep的信息
1 2 3 4 | -o Print each match, but only the match, not the entire line. -h Never print filename headers (i.e. filenames) with output lines. -w The expression is searched for as a word (as if surrounded by `[[:<:]]' and `[[:>:]]'; |
原始答案不适用于所有人的原因
最终,不管GREP的平台(原始版本)是什么,上面的POSIX答案都会更加可靠。
对于不带-o选项的grep的支持,第一个grep输出相关的行,tr将空间拆分为新行,最终grep只对相应的行进行过滤。
(附言:我知道大多数平台到目前为止,都已经为w…进行了修补。但总有落后的)
来自@adamrosenfield答案的"-o"解决方案
您可以将空格转换为换行符,然后转换为grep,例如:
1 2 | cat * | tr ' ' ' ' | grep th |
只需
1 2 3 4 5 6 | # awk '{for(i=1;i<=NF;i++){if($i~/^th/){print $i}}}' file the the the this thoroughly |
这比你想象的要简单。试试这个:
1 2 3 | egrep -wo 'th.[a-z]*' filename.txt #### (Case Sensitive) egrep -iwo 'th.[a-z]*' filename.txt ### (Case Insensitive) |
在哪里?
1 2 3 4 | egrep: Grep will work with extended regular expression. w : Matches only word/words instead of substring. o : Display only matched pattern instead of whole line. i : If u want to ignore case sensitivity. |
grep命令仅用于匹配和perl
1 | grep -o -P 'th.*? ' filename |
我对awk难以记忆的语法不满意,但我喜欢使用一个实用程序来实现这一点的想法。
似乎ack(如果使用ubuntu,则为ack grep)可以轻松做到这一点:
1 2 3 4 5 6 7 | # ack-grep -ho"\bth.*?\b" * the the the this thoroughly |
如果省略-h标志,则会得到:
1 2 3 4 5 6 7 8 9 10 11 12 | # ack-grep -o"\bth.*?\b" * some-other-text-file 1:the some-text-file 1:the the yet-another-text-file 1:this thoroughly |
另外,对于更复杂的搜索,您可以使用
1 2 3 4 | # echo"bug: 1, id: 5, time: 12/27/2010"> test-file # ack-grep -ho"bug: (\d*), id: (\d*), time: (.*)" --output '$1, $2, $3' test-file 1, 5, 12/27/2010 |
1 | cat *-text-file | grep -Eio"th[a-z]+" |
要搜索所有以"icon-"开头的单词,以下命令工作正常。我在这里使用的是ACK,它与grep类似,但具有更好的选项和良好的格式。
1 | ack -oh --type=html"\w*icon-\w*" | sort | uniq |
我也遇到了类似的问题,寻找grep/pattern regex和输出的"matched pattern found"。
最后,我使用了egrep(grep-e上的同一个regex或-g没有给出与egrep相同的结果)和选项-o
所以,我认为这可能是类似的(我不是一个正则表达式大师):
1 | egrep -o"the*|this{1}|thoroughly{1}" filename |
您也可以尝试PCREGRP。在grep中还有一个
维基百科:
1 2 3 4 5 6 7 8 9 10 11 12 13 | cat fruitlist.txt apple apples pineapple apple- apple-fruit fruit-apple grep -w apple fruitlist.txt apple apple- apple-fruit fruit-apple |
1 | $ grep -w |
摘自grep手册页:
-W:只选择那些包含构成整个单词的匹配项的行。测试是匹配的子字符串必须位于行的开头,或者前面有一个非单词组成字符。
下面是使用
1 | rg -o"(\w+)?th(\w+)?" |
它将匹配所有与
您可以这样将grep输出导入Perl:
1 2 | grep"th" * | perl -n -e'while(/(\w*th\w*)/g) {print"$1 "}' |