sed / regex:将bigrams拆分为新行(多行输入)

时间:2015-10-03 22:54:13

标签: regex sed grep

我想用sed将文本拆分为双字母组(两个相邻单词的集合)。我使用以下命令:

sed -r 's/(\\w+) (\\w+)/\\1 \\2\\n/g' input.txt >output.txt

问题是sed在每个第二个单词之后用新行分割输入,并在该序列之后继续(即在第三个单词处)。我希望它把第二个词作为下一个起点。

示例:

the quick brown fox jumped over the lazy dog
the squirrel ate my homework

结果:

the quick
brown fox
jumped over
the lazy
the squirrel
ate my

我想要的是:

the quick
quick brown
brown fox
fox jumped
jumped over
over the
the lazy
lazy dog
the squirrel
squirrel ate
ate my
my homework

我想我可以通过删除原始输入的第一个单词来运行另一个sed命令。但有没有办法在一个命令中获得所需的结果?

4 个答案:

答案 0 :(得分:2)

保持简单,只需使用awk:

$ awk '{for (i=1;i<NF;i++) print $i, $(i+1)}' file
the quick
quick brown
brown fox
fox jumped
jumped over
over the
the lazy
lazy dog
the squirrel
squirrel ate
ate my
my homework

清晰,简单,明显,简洁,强大,便携,高效等等......

我看到你在评论中询问三卦,对上述内容的调整显而易见:

$ awk '{for (i=1;i<(NF-1);i++) print $i, $(i+1), $(i+2)}' file
the quick brown
quick brown fox
brown fox jumped
fox jumped over
jumped over the
over the lazy
the lazy dog
the squirrel ate
squirrel ate my
ate my homework

答案 1 :(得分:1)

使用sed:

$ sed -r 's/ /  /g; s/ (\w+) / \1\n\1/g; s/  / /' input.txt
the quick
quick brown
brown fox
fox jumped
jumped over
over the
the lazy
lazy dog
the squirrel
squirrel ate
ate my
my homework

以上是在Linux上使用GNU sed进行测试的。在BSD(Mac OSX)上,尝试:

sed -r -e 's/ /  /g' -e 's/ (\w+) / \1\n\1/g' -e 's/  / /' input.txt

如何运作

  • s/ / /g

    这会使空格加倍,以便后面的命令正常工作。

  • s/ (\w+) / \1\n\1/g

    这需要每个单词和双倍:单个单词由单词的副本替换,后跟换行符,然后是单词的另一个副本。

  • s/ / /

    这会从输出中删除多余的空间。

答案 2 :(得分:1)

$ echo 'the quick brown fox jumped over the lazy dog' | \
  sed ': X; s/\(\w\+\) \(\w\+\) \(\w\+\)/\1 \2\n\2 \3/; t X'
the quick
quick brown
brown fox
fox jumped
jumped over
over the
the lazy
lazy dog

正如https://www.gnu.org/software/sed/manual/sed.html#Programming-Commands中所述,: X声明了一个标签X。如果前面的替换成功,t X会跳回X。也就是说,只要正则表达式保持匹配,我们就会循环。这几乎就像s///g;区别在于s///g不会重新扫描它替换更多匹配的部分,但是这个程序会。

答案 3 :(得分:1)

这可能适合你(GNU sed):

sed -r 's/(\S+) /\1\n&/2g' file

取代第二个符号;符号后跟一个空格,后跟一个换行符,后跟整个行的全局匹配。

另一种方法是:

sed -r 's/^\S+ (\S+)/&\n\1/;//P;D' file

此方法可以扩展为三元组:

sed -r 's/^\S+ (\S+ \S+)/&\n\1/;//P;D' file