首页 > 解决方案 > 使用 sed 将特定行移动到另一行下

问题描述

我需要用 newrdn 查找并替换 entryUUID,然后将该行移到另一行下。此文本文件将有超过 500k 的更改类型,因此无法移动到特定的行号。

文本文件中的原始行:

dn: uid=test@testing.com,ou=people,dc=example,dc=com
changetype: modrdn
deleteoldrdn: 1
newsuperior: ou=people,dc=example,dc=com
entryUUID: 6277b4d4e3-xxxx-xxxx-xxxx-xxxxxxxxxx

我想用 newrdn 替换 entryUUID,然后将此行移到以 changetype 开头的行下方。

理想输出:

dn: uid=test@testing.com,ou=people,dc=example,dc=com
changetype: modrdn
newrdn: 6277b4d4e3-xxxx-xxxx-xxxx-xxxxxxxxxx
deleteoldrdn: 1
newsuperior: ou=people,dc=example,dc=com

我正在使用以下命令;但是,它没有按预期工作(添加新的错误条目而不是移动行)

sed -i '/^changetype:*/a;'s/entryUUID:/newrdn:/g' file.txt

标签: linuxshellsed

解决方案


一种使用方式sed

具有多个条目的示例文件:

dn: uid=test@testing.com,ou=people,dc=example,dc=com
changetype: modrdn
deleteoldrdn: 1
newsuperior: ou=people,dc=example,dc=com
entryUUID: 6277b4d4e3-xxxx-xxxx-xxxx-xxxxxxxxxx
---
dn: uid=test@testing.com,ou=people,dc=example,dc=com
changetype: modrdn
deleteoldrdn: 1
newsuperior: ou=people,dc=example,dc=org
entryUUID: 7277b4d4e3-xxxx-xxxx-xxxx-xxxxxxxxxx
sed -e '/^deleteoldrdn:/{N;h;d}; /^entryUUID:/{s/^entryUUID:/newrdn:/;G}' input.txt
dn: uid=test@testing.com,ou=people,dc=example,dc=com
changetype: modrdn
newrdn: 6277b4d4e3-xxxx-xxxx-xxxx-xxxxxxxxxx
deleteoldrdn: 1
newsuperior: ou=people,dc=example,dc=com
---
dn: uid=test@testing.com,ou=people,dc=example,dc=com
changetype: modrdn
newrdn: 7277b4d4e3-xxxx-xxxx-xxxx-xxxxxxxxxx
deleteoldrdn: 1
newsuperior: ou=people,dc=example,dc=org

这个怎么运作:

/^deleteoldrnd:/{N;h;d}

每次读取以开头的行时deleteoldrnd:,还要读取下一行并将其添加到当前模式空间( ),用模式空间 ( N) 替换当前保持空间h,删除模式空间并从新行重新开始 ( d)。

/^entryUUID:/{s/^entryUUID:/newrdn:/;G}

每次entryUUID:读取以 开头的行时,将前缀更改为newrdn:,然后将保持空间附加到模式空间(G),(此时的保持空间是原始文件中紧接在前面的deleteoldrdnand行)。newsuperior然后自动打印出图案空间。

如果您使用的是 GNU sed(因为您标记了这个 [linux],这似乎很可能),一个变体是:

sed -e '/^deleteoldrdn:/{N;h;z;N;s/\nentryUUID:/newrdn:/;G}' input.txt 

它使用 GNU 扩展z在以相同的命令序列读取 UUID 行之前擦除模式空间,而不是将其分成两部分。


推荐阅读