【问题标题】:Sed replace blocks of text from 2 filesSed 替换 2 个文件中的文本块
【发布时间】:2013-09-16 13:52:21
【问题描述】:

我有 2 个文件:oldfile 和 newfile,它们的结构相似,它们只包含细微的变化

我需要用旧文件中的一个块替换新文件中的一个文本块(作为 bash 脚本)

在旧文件中我有:

...文字

#######################################################################
# LDAP Settings
LDAPUrl = ldap://xxx
LDAPSearchBase = CN=Users,DC=xx,DC=xxx,DC=xx
LDAPSearchSecondary = ***
LDAPSearchFilter = cn=xxx
LDAPUser = CN=***,CN=Users,DC=xx,DC=xxx,DC=xx
LDAPPassword = ***
LDAPAuthenticateServer = ldap://test:389
ProsourceKey = ****

#######################################################################

...其他文字

newfile 是相同的,只是参数值发生了变化。

我使用 sed 从 oldfile 中获取此输出,如下所示: getldap=sed -n '/^# LDAP Settings$/,/^$/p' oldfile > ldap.tmp(将其存储在 ldap.tmp 中)

使用了分隔符:# LDAP Settings 和包含空格的空行

现在我想将该输出插入到 newfile 并替换现有的类似文本。

【问题讨论】:

  • 那你有什么问题或问题?

标签: bash shell scripting sed


【解决方案1】:

适合工作的正确工具,这里 awk 比 sed 更能满足您的要求。

这个 awk 应该可以工作:

awk -F '[= ]+' 'FNR==NR{a[$1]=$0;next} $1 in a{$0=a[$1]}1' oldfile newfile

更新:要将替换限制为 # LDAP Settings,只有您可以这样做:

awk -F '[= ]+' 'FNR==NR && /^# LDAP Settings$/{r=1;next} FNR==NR && r && /^$/{r=0;next} 
   r && FNR==NR{a[$1]=$0;next} FNR!=NR{if($1 in a)$0=a[$1];print}' oldfile newfile

说明:

这个 awk 命令可以分为 2 个部分:

-F '[= ]+' - Use field separator = or space or both
FNR == NR - First file is being processed
FNR != NR - Second file is being processed
FNR == NR && /^# LDAP Settings$/ - In 1st file if # LDAP Settings is found set r=1
r && FNR==NR - a[$1]=$0 - In 1st file if r=1 then
a[$1]=$0 - Store 1st field as key in array a and $0 (whole line) as value
FNR==NR && r && /^$/ - In 1st file if r=1 and empty line found then set r=0

FNR!=NR{if($1 in a)$0=a[$1];print} In 2nd file if $1 exists in a then set whole line as 
                                   value of array a. Then print the whole line

【讨论】:

  • 对不起,但这似乎不起作用,如果我理解正确,这应该替换 [= ] 之后的所有值,但我只想要那个特定的块,还有其他我不想成为的值更换。此外,当我运行它时,它对新文件的更改没有任何作用
  • 发布新文件示例。 awk 也不会更改新文件,您需要将输出重定向到单独的文件,然后将其移回新文件,例如 awk -F '[= ]+' 'FNR==NR{a[$1]=$0;next} $1 in a{$0=a[$1]}1' oldfile newfile > _temp && mv _temp newfile
  • 好的,这在某种程度上确实有效:它成功替换了块,但还有其他行带有 =,最后我在新文件中得到了很多垃圾数据
  • 例如:###################################### ############################### # 生产/测试时间 - ImporterEngineInitialisation=on # 生产/测试时间 - ImporterEngineInitialisation=on # 生产/测试时间 - ImporterEngineInitialisation=on # 生产/测试时间 - ImporterEngineInitialisation=on # 生产/测试时间 - ImporterEngineInitialisation=on CatalogImporterEngineInitialisation=on ################### ################################################# # # 生产/测试时间 - ImporterEngineInitialisation=on
  • 假设从# LDAP Settings开始替换并以空行结束是否相同?
【解决方案2】:

以下sed 命令将使用 ldap.tmp 的内容替换 LDAP 设置部分:

sed '/^# LDAP Settings$/,/^$/ {//!d}; /^# LDAP Settings$/r ldap.tmp' newfile

【讨论】:

  • 谢谢,这行得通,唯一的问题是我得到 2 # LDAP Settings 行
  • 你能从 ldap.tmp 中删除 LDAP 设置行吗?
  • 我不知道该怎么做,如果我使用另一个分隔符,如 LDAPUrl = ,那么我的 tmp 文件中没有任何输出
  • 最简单的方法是在创建 ldap.tmp 时使用tail 删除第一行,如下所示:sed -n '/^# LDAP Settings$/,/^$/p' file | tail -n +2 > ldap.tmp
猜你喜欢
  • 2012-10-14
  • 2019-01-19
  • 2022-10-21
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 2019-02-07
  • 2012-04-22
  • 2014-12-22
相关资源
最近更新 更多