在bash中多行匹配后附加一个字符串 [英] Append a string after a multiple line match in bash
问题描述
在bash中多行匹配后,我需要一个sed
或awk
命令来打印一行.例如,将该文件作为输入:
I would need a sed
or awk
command to print a line after a multiple line match in bash. For example having this file as input:
admin:
users:
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
..我需要将其作为输出:
..I would need to have this as output:
admin:
users:
NEW USER
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
正则表达式应与前两行admin: users:
匹配,然后附加NEW USER
行.
The regex should match the first two lines admin: users:
and then append NEW USER
line.
如何执行此操作?我应该使用sed还是awk?如何? 谢谢
How to do this? Should I use sed or awk? How? Thank you
推荐答案
使用sed
在/^[a-z_]\+:/
和/^$/
之间定界块,因此您可以在一个块中进行Somme处理:
With sed
Delimit block between /^[a-z_]\+:/
and /^$/
, so you could do somme process in one block:
sed -e $'/^admin:/,/^$/{/users:/a\ NewUser\n}'
可以这样写:
NEWUSER="user2017"
sed -e "/^admin:/,/^$/{
/users:/a\ - $NEWUSER
}"
(通过使用双引号,我可以使用命令行或脚本中的变量)
(By using double quotes, I could use variable from commandline or script)
这将呈现:
admin:
users:
- user2017
- user1
- user2
read_only:
users:
- user3
...
或纯 bash ...
Or pure bash...
myadduser () {
local crt= line;
while IFS= read line; do
echo "$line";
[ "$line" ] && {
[ "${line:0:1}" != " " ] && crt=${line%:} || {
[ "${line//*([: ])}" = "users" ] &&
[ "$crt" = "${2:-admin}" ] &&
printf " - %s\n" $1
}
};
done
}
可以通过以下方式使用:
which could by used:
myadduser NewAdminUser <file.txt
admin:
users:
- NewAdminUser
- user1
- user2
read_only:
users:
- user3
...
或带有可选的第二个参数:
or with optional second argument:
myadduser NewWriteUser write_only
admin:
users:
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- NewWriteUser
- user4
access_only:
users:
- user5
- user6
但是,请
阅读 Sobrique的很好的答案!
带有 perl 或 c 的问题以进行最终编程,您可能会找到合适的库.
With perl or python for prototyping like by using c for finalized programmation, you may find apropriate libraries.
使用 shell 的问题中的任何此类库也可以.
Using any of this libraries in shell could be done too.
perl -MYAML -E 'undef$/;$s = Load(<>);say@{$s->{admin}->{users}}[0];'
管理员用户数
perl -MYAML -E 'undef$/;$s = Load(<>);say scalar@{$s->{admin}->{users}};'
这篇关于在bash中多行匹配后附加一个字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!