我想要一个sed脚本,该脚本可以消除文本文件中一行或多行上的重复单词。例如:
this is is is a text file file it is littered with duplicate words
words words on one or more lines lines
lines
lines
应转换为:
this is a text file it is littered with duplicate words
on one or more lines
此awk脚本产生正确的输出:
{
for (i = 1; i <= NF; i++) {
word = $i
if (word != last) {
if (i < NF) {
next_word = $(i+1)
if (word != next_word) {
printf("%s ", word)
}
} else {
printf("%s\n", word)
}
}
}
last = word
}
但是我真的很想要一个sed“单线”。
答案 0 :(得分:1)
这至少在示例输入中可用于GNU sed:
$ sed -Ez ':a;s/(\<\S+)(\s+)\1\s+/\1\2/g;ta' infile
This is a text file and is littered with duplicate words
on one or more lines
使用-E
选项可以避免逃避捕获组括号和+
量词。
-z
将输入视为空字节分隔,即视为一行。
该命令的结构如下
:a # label
s///g # substitution
ta # jump to label if substitution did something
替换为:
s/(\<\S+)(\s+)\1\s+/\1\2/g
(\<\S+)
–一个完整的单词(单词边界的开头,一个或多个非空格字符(\s+)
–第一个单词后的空格为空白\1\s+
–再次是第一个单词加上其后的空白这将保留第一个单词后的空白,并删除重复项后的空白。
请注意,-E
,-z
,\<
,\S
和\s
都是POSIX sed的GNU扩展。
答案 1 :(得分:0)
使用sed,您可以使用
sed -E 's/([a-z]+) +\1/\1/g'
请注意,它适用于重复项。不适用于一式三份或换行符。
可以通过连接所有行并循环来解决此问题。
sed -E ':a;N;s/(\b[a-z]+\b)([ \n])[ \n]*\b\1\b */\1\2/g;ba'
答案 2 :(得分:0)
sed -En '
H
${
g
s/^\n//
s/(\<([[:alnum:]]+)[[:space:]]+)(\2([[:space:]]+|$))+/\1/g
p
}
' file
This is a text file with duplicate words
on one or more lines
其中
H
-将每行追加到保留空间${...}
-在最后一行,执行随附的命令g
-用保留空间的内容替换模式空间s/^\n//
-删除开头的换行符(H
在第一行的副作用) s/(\<([[:alnum:]]+)[[:space:]]+)(\2([[:space:]]+|$))+/\1/g
..1..2............2............1..........................