对所有人来说,
我花了很多时间寻找解决方案,但找不到它。
仅仅为了背景,我有一个包含数千条记录的文本数据库。每条记录都由以下人员描述:
“0 @nnnnnn @Xnnn”//没有引号
记录在他们自己的行上有很多字段,但我感兴趣的字段是搜索和替换子字符串(通知空格):
“1 X94 User1.faculty.ventura.ca”//没有引号
我想使用sed将子字符串“.faculty.ventura.ca”更改为“.students.moorpark.ut”,在行上更改其他内容,全局更改所有记录。
我已经测试了很多带有负面结果的东西。
如何做到这一点?
感谢您的帮助。 鲍勃佩雷斯(robertperez1957@gmail.com)
答案 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
结束,以便每行多次更改。请注意,这将输出到标准输出。你可能想要添加
> 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都会被认为是合适的。