sed - 消除跨行重复的单词
问题描述
我想要一个 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 “单线”。
解决方案
这适用于 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 扩展。
推荐阅读
- java - 如何在片段中实现按钮而不使应用程序崩溃?
- flutter - 选择何时何地在本地保存数据
- python - Excel 内置格式和 openpyxl 中的自定义格式之间有什么区别吗?
- webrtc - 如何使用 PeerJS 添加屏幕共享功能?
- javascript - react-use-gestue 的 onDoubleClick 不起作用
- c# - 为什么此通用代码中不允许隐式转换?
- java - 在 Spock 上调用服务获取空对象
- javascript - VS Code:无法写入用户设置。请打开用户设置以更正其中的错误/警告,然后重试
- javascript - 验证:允许重复但在 Mongoose Schema 上标记
- asp.net-core - 在 ASP.NET Core 应用程序中使用更新版本的库