我正在寻找一个正则表达式来删除一个字符单词。我不介意使用perl
,awk
,sed
还是bash
内置插件。
测试用例:
$ echo "a b c d e f g h ijkl m n opqrst u v" | $COMMAND
期望的输出:
ijkl opqrst
到目前为止我尝试过:
$ echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/ . //g'
acegijkln opqrstv
我在猜测:
a
未删除,因为c
仍然存在,因为删除b
后,之前就没有空格了尝试#2:
$ echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/\w.\w//g'
s v
在这里,我根本不知道发生了什么。
欢迎任何帮助+解释,我想学习。
答案 0 :(得分:7)
您必须使用单词边界\b
(或)\<
和\>
分别匹配单词开头和结尾的空字符串。
echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/\b\w\b \?//g'
(OR)
echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/\<.\> \?//g'
答案 1 :(得分:4)
您可以简单地使用grep
:
echo "a b c d e f g h ijkl m n opqrst u v" | grep -o '[a-z]\{2,\}'
其中正则表达式匹配任何由至少2个字符组成的单词。
-o
中的grep
选项会打印匹配的模式(而不是整行)。
答案 2 :(得分:2)
尽管如此,Awk
并不是最有效的方法,只是因为它使用length()
字符串函数标记为awk而回答。它符合POSIX
,因此没有可移植性问题。
echo "a b c d e f g h ijkl m n opqrst u v" | \
awk '{for(i=1;i<=NF;i++) {if (length($i)>1) { printf "%s ", $i }} }'
ijkl opqrst
答案 3 :(得分:1)
Perl解决方案:只需过滤length
echo "a b c d e f g h ijkl m n opqrst u v" | perl -lanE \
'say join " ", grep {length($_) > 1} @F'
答案 4 :(得分:1)
只是为了好玩,另一种选择:将空格转换为换行符并查找至少包含2个字符的行
$ echo "a b c d e f g h ijkl m n opqrst u v" | tr ' ' '\n' | grep .. | paste -sd " "
ijkl opqrst
答案 5 :(得分:0)
不熟悉任何Linux弹簧工具,这有点猜测,但我认为(a)你想要的正则表达式是
(?:\s\w\b|\b\w\s)
像
$ echo "a b c d e f g h ijkl m n opqrst u v" | sed 's/(?:\s\w\b|\b\w\s)//g'
这将替换任何一个没有任何空格的任何单个字符。
答案 6 :(得分:0)
awk中的另一个人。非空格([^ ]
)被视为单词。随意用你的单词定义替换它。
$ awk '{while(sub(/^[^ ] | [^ ]$/,"")||sub(/ [^ ] /," "));}1'
使用sub
它会用空格替换[a space][non-space][a space]
元组
并从记录的开头和结尾删除单个字符和前导/尾随空格。它在while
中,所以它一直在做,直到没有命中。测试它:
$ echo "a b c d e f g h ijkl m n opqrst u v"|awk '{while(sub(/^[^ ] | [^ ]$/,"")||sub(/ [^ ] /," "));}1'
ijkl opqrst
答案 7 :(得分:-1)
echo "a b c d e f g h ijkl m n opqrst u v" | grep -wo "\b[a-z][a-z]\+\b"