![使用流编辑器 (Sed) 将所有名称替换为替代名称](https://linux22.com/image/1305195/%E4%BD%BF%E7%94%A8%E6%B5%81%E7%BC%96%E8%BE%91%E5%99%A8%20(Sed)%20%E5%B0%86%E6%89%80%E6%9C%89%E5%90%8D%E7%A7%B0%E6%9B%BF%E6%8D%A2%E4%B8%BA%E6%9B%BF%E4%BB%A3%E5%90%8D%E7%A7%B0.png)
我在做任务时遇到了这个问题。什么都没用。有人能帮我吗?
编写一个 sed 脚本,将所有名称替换为替代名称,
搜索所有符合以下条件的词:
- 以大写字母开头,
- 长度超过两个字母,
- 前面有一个空白的地方,
- 空格之前的字符不是结束句子的标点符号。
用“Derp”+该单词的最后两个字符替换这些单词。
答案1
在 sed 中执行此操作相当麻烦,但这里有一个版本,只要有一个字符(我选择%
)永远不会出现在输入中,它就可以工作。该字符用于标记。
words
假设您有一个名为以下内容的文本文件:
Will He beat Sit Down Boy Oh Not now Latch Wi, Qq or Spat? GNU Hurd, protocols on GNU Mach. The Hurd versus Unix.
下面的bash
脚本可以完成这个工作:
cat words
sed 's/ [A-Z][A-Za-z]*[A-Za-z]\{2\}/%&/g' words|tee a
sed 's/\([.!?]\)%/\1/g' a|tee b
sed 's/% [A-Za-z]*\([A-Za-z]\{2\}\)/ Derp\1/g' b|tee c
上面的输出将是(我用新行分隔每个):
Will He beat Sit Down Boy Oh Not now Latch Wi, Qq or Spat? GNU Hurd, protocols on GNU Mach. The Hurd versus Unix.
Will He beat% Sit% Down% Boy Oh% Not now% Latch Wi, Qq or% Spat?% GNU% Hurd, protocols on% GNU% Mach.% The% Hurd versus% Unix.
Will He beat% Sit% Down% Boy Oh% Not now% Latch Wi, Qq or% Spat? GNU% Hurd, protocols on% GNU% Mach. The% Hurd versus% Unix.
Will He beat Derpit Derpwn Derpoy Oh Derpot now Derpch Wi, Qq or Derpat? GNU Derprd, protocols on DerpNU Derpch. The Derprd versus Derpix.
工作原理如下:
- 第一行只是打印文件,因此您可以看到起始位置。
- 第二行用 标记所有以空格开头且长度超过 2 个字符的大写单词
%
。因此,它将例如标记Latch
为% Latch
。注意空格,我将其称为空格词。 - 第三行将删除所有以句子结尾的字符开头的空格词的标记(为简单起见,我只选择了
.
、!
或?
- 您可以添加其他字符,例如)
或诸如此类,如果需要) - 第三行将进行实际转换 - 即替换所有标有
Derp
的空格词,即该空格词的最后两个字符%
DerpXX
XX
请注意,这里没有涉及一些技术细节,例如:
- 这只适用于美国 ASCII 单词(例如,不适用于所有法语单词,例如
Être
) - 可能需要考虑其他字符(例如,即使 in 前面有一个单词,它是否被视为一个单词
Oceans
?)"Oceans Eleven"
"
- 不适用于非空格的空白(例如制表符)
等等。
为了使其成为纯粹的sed
脚本,只需连接:
sed '
s/ [A-Z][A-Za-z]*[A-Za-z]\{2\}/%&/g
s/\([.!?]\)%/\1/g
s/% [A-Za-z]*\([A-Za-z]\{2\}\)/ Derp\1/g
' words
显然,在现实世界中,我不会sed
做这样的任务。不过,我可能也不会有这样的任务……:)
答案2
这可能对你有用:
sed ':a;s/\([^.!?] \)[A-Z][A-Za-z]*\([A-Za-z]\{2\}\)\>/\1\nDerp\2/;ta;s/\n//g' file