删除一个字符的单词

时间:2017-01-17 09:40:44

标签: regex bash perl awk sed

我正在寻找一个正则表达式来删除一个字符单词。我不介意使用perlawksed还是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

在这里,我根本不知道发生了什么。

欢迎任何帮助+解释,我想学习。

8 个答案:

答案 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()字符串函数标记为而回答。它符合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'

这将替换任何一个没有任何空格的任何单个字符。

Check the regex out here at regex101

答案 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"