如果一个句子包含2个相同的连续单词,我在查看文件时遇到了挑战。如果是这样,你打印这个词;否则,你不打印句子。
示例:
abc2 1 def2 3 abc2
F4
--------------
dea 123 123 zy45
12 12
abc cd abc cd
xyz%$@! xyz%$@! kk
xyzxyz
abc h h h h
运行程序后,输出将为:
dea 123 zy45
12
xyz%$@! kk
abc h h h
3
这是我到目前为止所做的:
sed '/\([^\([^ ]\+\)[ ]\+\1]\)/d' F4 >|tmp
到目前为止我得到了这个,但这只是将具有双字的句子和不具有双字的句子分开。
答案 0 :(得分:1)
您的sed
表达非常准确。但是,它需要一些修改才能使它工作:
$ sed -nr 's/\b(\S+)\s+\1(\s|$)/\1/p' file
dea 123 zy45
12
xyz%$@! kk
abc h h h
您的想法是您已经实施的:将给定的字词与[^ ]
匹配,看看您是否再次与\1
匹配。我添加的所有内容都被\1
替换,因此重复的块会消失。
使用[^ ]
代替\S
,[ ]
,而不是\s
。另请注意使用\b
作为单词边界来防止fedorqui qui
等误报以及使用\1(\s|$)
来防止其他误报,例如hello helloa
(感谢WalterA对于例子!)。注意\s|$
用于匹配空格或行尾的用法; \b
匹配任何无字字符,这使得它对xyz%$@! kk
的情况无效。
为防止打印所有行,我们使用sed -n
。这样,我们只打印(使用p
)那些经过定义的正则表达式的文件。
请注意使用-r
来摆脱所有转义为捕获组的内容。没有它,命令将是:
sed -n 's/\b\([^ ]\+\)[ ]\+\1/\1/p' file
让我们用更全面的输入来测试它:
$ cat a
abc2 1 def2 3 abc2
F4
--------------
dea 123 123 zy45
12 12
abc cd abc cd
xyz%$@! xyz%$@! kk
xyzxyz
fedorqui qui
hello helloa
abc h h h h
$ sed -nr 's/\b(\S+)\s+\1(\s|$)/\1/p' a
dea 123zy45
12
xyz%$@!kk
abc hh h
答案 1 :(得分:0)
我一直在寻找一个似乎很容易的sed
解决方案。也许在这种情况下awk
更好(F4
是输入文件):
awk '{
for (i=2; i<=NF; i++) {
if ($(i-1)==$i) {
$i="";
printf("%s\n", $0);
break;
}
}
}' F4
我对这个解决方案并不满意,因为它会在删除加倍的单词后在$0
中留下一个双FieldSep,但字面上OP确实没有看到空格或制表符也应该被删除。