SED搜索并替换数据库文件中的子字符串

时间:2013-02-28 19:09:33

标签: sed

对所有人来说,

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

仅仅为了背景,我有一个包含数千条记录的文本数据库。每条记录都由以下人员描述:

“0 @nnnnnn @Xnnn”//没有引号

记录在他们自己的行上有很多字段,但我感兴趣的字段是搜索和替换子字符串(通知空格):

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

我想使用sed将子字符串“.faculty.ventura.ca”更改为“.students.moorpark.ut”,在行上更改其他内容,全局更改所有记录。

我已经测试了很多带有负面结果的东西。

如何做到这一点?

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

1 个答案:

答案 0 :(得分:1)

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

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

这会将1 X94 XXXXXX.faculty.ventura.ca格式的所有记录替换为1 X94 XXXXX.students.moorpark.ut

以下是有关这一切的详细信息:

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

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

> mynewdatabasefile.name

到您行的末尾,将所有输出保存到文件中。 (这对你的终端不会有太大帮助。)

根据您的评论编辑

如果您要将1 F94 bperez.students.Napvil.NCC替换为1 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到任意字符中的0个并保存为以后的匹配” )尽可能。 尝试使用:

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

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