我只需要打印由 3 个字符组成的单词,但是单词文档是一个编号列表。
这是我必须回答的确切问题:
使用文件上的字符类
sed
命令,查找所有只有三个字符长的动物名称[[:lower:]]
animals
(3分)。
这是我尝试过的:
cat animals | sed '/{[:lower:]].../d'
cat animals | sed '/{[:lower:]]/d'
sed '/[[:lower:]]{3}/d' animals
animals
这是我试图从(文件)中查找单词的文件:
01. aardvark
02. badger
03. cow
04. dog
05. elephant
06. fox
07. goose
08. horse
09. iguana
10. jackal
11. koala
12. lamb
13. mongoose
14. narwhal
15. onyx
16. pig
17. quail
18. rat
19. snake
20. tiger
21. umbrellabird
22. vulture
23. walrus
24. xerus
25. yak
26. zebra
我刚刚发现代码中不能多次包含 [[:lower:]] 有没有办法做到这一点?
答案1
sed
是一个流编辑器,这意味着它读取文本、编辑文本并输出结果。它不一定需要处理文件,只需要处理文本流。 (在您的情况下,文本流来自文件,因此没有实际差异。)
使用sed
你有几个选择
- 删除所有不包含三个连续小写字母的行,剩下的行将被传递(并打印)。
- 仅打印恰好包含三个连续小写字母的行。
无论哪种情况,您都需要确保这三个字符前面有一个空格,并且后面没有任何内容。
这将匹配四个(或更多)字符的单词并删除匹配的行。请注意,我们没有绑定序列的末端,因此它们会很高兴地在较长序列的中间匹配
sed '/[[:lower:]][[:lower:]][[:lower:]][[:lower:]]/d' animals
这将适用于给定的文件,但它没有考虑到可能存在两个(甚至只有一个)字母的动物的可能性。 (例如,想想“牛”)。所以我们需要把它们淘汰掉。此时我们需要告诉sed
每行有多个操作依次应用。我们还需要引入一个新字符$
,它声明正则表达式必须绑定到行尾:
- 如果我们在一行中找到四个字符,则删除该行
- 如果我们找到一个空格,两个字母,然后是行尾,则删除该行
- 如果我们找到一个空格、一个字母、然后是行尾,则删除该行
这可以写成长形式,如下所示:
sed -e '/[[:lower:]][[:lower:]][[:lower:]][[:lower:]]/d' -e '/ [[:lower:]][[:lower:]]$/d' -e '/ [[:lower:]]$/d' animals
如果您有合适的版本,sed
可以将其折叠成更易读的形式。 (寻找-r
旗帜。)
答案2
我正在使用sed (GNU sed) 4.2.2
并且得到了你想要的结果:
sed 's/^[[:digit:]]\{2\}[[:punct:]][[:space:]]\([[:lower:]]\{3\}\)/\1/gm' animals.txt | sed '/[[:lower:]]\{4\}/d'
它执行以下步骤:
- 找到以 2 位数字开头,后跟标点符号(“.”)、空格,然后是至少包含 3 个小写字符的单词的行;
- 在该行中,选择匹配的小写字符组;
- 根据上一步的结果,删除包含 4 个或更多小写字符的单词。
输出仅包含恰好 3 个小写字符的单词:
cow
dog
fox
pig
rat
yak
作为参考,GNU sed 使用这个正则表达式语法。
答案3
最直接的方法是这样的:
$ sed -n '/^....[a-z]\{3\}$/p' animals
03. cow
04. dog
06. fox
16. pig
18. rat
25. yak
为了满足您使用的要求,[[:lower:]]
您可以像这样修改上面的内容:
$ sed -n '/^....[[:lower:]]\{3\}$/p' animals
03. cow
04. dog
06. fox
16. pig
18. rat
25. yak
您还可以将 切换....
为明确大小的序列:
$ sed -n '/^.\{4\}[[:lower:]]\{3\}$/p' animals
03. cow
04. dog
06. fox
16. pig
18. rat
25. yak
参考
答案4
你很接近。匹配3个元素的基本思想是朝着正确的方向。
BRE 存在语法错误,因为{}
需要反斜杠(或使用-E
)。
但是,您的正则表达式:[[:lower:]]\{3\}
将匹配任何具有三个或更多的人物。
你需要锚正则表达式,可能从space
( ) 到
end
( $
):
$ <infile sed -n '/ [[:lower:]]\{3\}$/p'
请注意,默认情况下该命令不会打印,并且仅在匹配的行上p
打印。也可以反过来写:
$ <infile sed '/ [[:lower:]]\{3\}$/!d'
即:默认打印,逐行打印不是匹配的,则删除(d
)。
或者,您可以使用单词边界:
$ <infile sed '/\b[[:lower:]]\{3\}\b/!d'
或者:
$ <infile sed '/\<[[:lower:]]\{3\}\>/!d'
也许,使用 ERE 正则表达式:
$ <infile sed -E '/\b[[:lower:]]{3}\b/!d'
如果您只需要动物名称,请使用:
$ <infile sed -E '/.*\<([[:lower:]]{3})\>/!d;s//\1/'
cow
dog
fox
pig
rat
yak