0

对所有人来说,

我花了很多时间寻找解决方案,但找不到。

仅作为背景,我有一个包含数千条记录的文本数据库。每条记录由 :

"0 @nnnnnn@ Xnnn" // 没有引号

记录在自己的一行上有很多字段,但我有兴趣搜索和替换子字符串(注意空格)的字段:

" 1 X94 User1.faculty.ventura.ca" // 没有引号

我想使用 sed 将子字符串“.faculty.ventura.ca”更改为“.students.moorpark.ut”,在全球范围内不更改所有记录。

我已经测试了很多东西,结果都是负面的。

如何才能做到这一点 ?

感谢您的帮助。鲍勃·佩雷斯 (robertperez1957@gmail.com)

4

2 回答 2

1

如果我理解正确,你想要这个:

sed 's/1 X94 \(.*\).faculty.ventura.ca/1 X94 \1.students.moorpark.ut/' mydatabase.file

这会将表单的所有记录替换1 X94 XXXXXX.faculty.ventura.ca1 X94 XXXXX.students.moorpark.ut

以下是所有功能的详细信息:

  • ''让您的脚本中有空格和其他混乱。
  • s/ 意味着替代
  • 1 X94 \(.*\).faculty.ventura.ca 是您将要替换的内容。将\(.*\)任何内容存储在该正则表达式中以用于替换
  • 1 X94 \1.students.moorpark.ut 是用什么来替换你找到的东西。\1 填写第一个匹配的内容\(.*\)。(您可以在一行中有多个,然后下一个将是 \2。)
  • 最后/只是告诉 sed 你已经完成了。如果您的数据库没有用于分隔其记录的换行符,您需要以 , 结尾/g,以便每行多次进行此更改。
  • mydatabase.file 应该是数据库的文件名。

请注意,这将输出到标准输出。您可能需要添加

> mynewdatabasefile.name

到行尾,将所有输出保存在文件中。(这对你的终端没有多大好处。)

编辑,根据您的评论

如果要替换1 F94 bperez.students.Napvil.NCC1 F94 bperez.JohnSmith.customer,可以使用另一组\(.*\),如:

sed 's/1 X94 \(.*\).\(.*\).Napvil.NCC/1 X94 \1.JohnSmith.customer/' 251-2.txt

这与上面类似,只是它匹配两个存储的参数。在此示例中,\1计算结果为bperez并且\2计算结果为students。我们匹配\2,但不要在表达式的替换部分使用它。您可以使用任意数量的存储参数来执行此操作。(Sed 可能有一些限制,但我从来没有打过足够复杂的字符串来打它。)例如,我们可以将 sed 脚本设为'\(.\) \(...\) \(.*\).\(.*\).\(.*\).\(.*\)/\1 \2 \3.JohnSmith.customer/',这将使 \1 = 1, \2 = X94, \3 = bperez,\4 = Napvil 和 \5 = NCC,我们将忽略 \4 和 \5。虽然这实际上不是最好的答案 - 只是表明它可以做到。这不是最好的,因为它更丑,也因为它更容易接受。然后它会在一行上进行查找和替换2 Z12 bperez.a.b.c,这可能不是你想要的。我在编辑中输入的查找查询尽可能具体,同时仍然足够通用以适合您的任务。

另一个编辑!

你知道我怎么说“尽可能具体”吗?由于.性格特殊,我没有。事实上,我很一般。意思是“.完全匹配任何字符”,而不是“匹配句点”。正则表达式是“贪婪的”,尽可能地匹配,所以\(.*\).\(.*\)总是尽可能地填充第一个\(.*\) (这就是说,“将 0 用于许多字符并将其保存为以后的匹配”)。尝试使用:

    sed 's/1 X94 \(.*\)\.\(.*\).Napvil.NCC/1 X94 \1.JohnSmith.customer/' 251-2.txt

这个额外的\充当转义序列,并将.“任何字符”更改为“只是句点”。仅供参考,因为我不(但应该)逃避其他时期,技术上 sed 将被1 X94 XXXX.StdntZNapvilQNCC视为有效匹配。因为.意味着任何字符,Z 或 Q 都将被认为是合适的。

于 2013-02-28T23:08:16.320 回答
0

以下教程帮助我 sed - 替换文件中的子字符串

尝试使用-i前缀直接替换文件中的相同内容

sed -i 's/unix/linux/' file.txt

于 2015-08-26T22:21:16.110 回答