Linux 使用sed在另一行下移动特定行
我需要找到entryUUID并将其替换为newrdn,然后将该行移到另一行下。此文本文件将具有超过500k的变更类型,因此移动到特定行号将不起作用 文本文件中的原始行:Linux 使用sed在另一行下移动特定行,linux,shell,sed,Linux,Shell,Sed,我需要找到entryUUID并将其替换为newrdn,然后将该行移到另一行下。此文本文件将具有超过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
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
:
具有多个条目的示例文件:
dn:uid=test@testing.com,ou=people,dc=example,dc=com
更改类型:modrdn
deleteoldrdn:1
newsuperior:ou=people,dc=example,dc=com
入口UUID:6277b4d4e3-xxxx-xxxx-XXXXXXXXX
---
dn:uid=test@testing.com,ou=people,dc=example,dc=com
更改类型:modrdn
deleteoldrdn:1
newsuperior:ou=people,dc=example,dc=org
入口UUID:7277b4d4e3-xxxx-xxxx-XXXXXXXXX
sed-e'/^deleteoldrdn:/{N;h;d}/^entryUUID://{s/^entryUUID:/newrdn://;G}'input.txt
dn:uid=test@testing.com,ou=people,dc=example,dc=com
更改类型:modrdn
新域名:6277b4d4e3-xxxx-xxxx-XXXXX-XXXXXXXXX
deleteoldrdn:1
newsuperior:ou=people,dc=example,dc=com
---
dn:uid=test@testing.com,ou=people,dc=example,dc=com
更改类型:modrdn
新域名:7277b4d4e3-xxxx-xxxx-XXXXX-XXXXXXXXX
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
),(此时的保留空间是原始文件前面的deleteoldrdn
和newsuperior
行)。然后,图案空间会自动打印出来
如果您使用的是GNU sed(可能是因为您标记了这个[linux]),则有一个变体:
sed-e'/^deleteoldrdn://{N;h;z;N;s/\nentryUUID:/newrdn://;G}input.txt
它使用GNU扩展名
z
在读取同一命令序列中的UUID行之前擦除模式空间,而不是将其拆分为两行。您也可以使用ed
,而不是使用sed-i
就地编辑文件,由于它将一个文件作为一个整体来处理,而不是一次处理一个孤立的行,因此它具有移动行的命令,这大大简化了工作。使用与mysed相同的输入文件回答:
$ ed -s input.txt <<'EOF'
g/^entryUUID:/s/^entryUUID:/newrdn:/\
m -3
w
EOF
$ cat 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
$ed-s input.txt这可能适合您(GNU-sed):
打印任何行直到一个开头changetype:
,打印此行并将其后面的行收集到保留空间中,直到行开始entryUUID:
。用newrdn:
替换该字符串并打印当前行。将保留空间中收集的行减去前导换行符后追加并打印它们。打印所有其他行
另一种解决方案:
sed '/^changetype:/{:a;N;s/^entryUUID:/newrnd:/m;Ta;s/\(\n.*\)\(\n.*\)/\2\1/}' file
哦,档案中有多个这样的案例,还是只有一个?@Shawn档案中有多个这样的案例。
sed -n '/^changetype:/{p;:a;n;/^entryUUID:/bb;H;ba;:b;s//newrdn:/p;z;x;s/.//};p' file
sed '/^changetype:/{:a;N;s/^entryUUID:/newrnd:/m;Ta;s/\(\n.*\)\(\n.*\)/\2\1/}' file