在bash中的多行匹配后追加字符串
我需要一个在bash中的多行匹配后追加字符串,bash,awk,sed,perl,python,c,shell,Bash,Awk,Sed,Perl,Python,C,Shell,我需要一个sed或awk命令在bash中的多行匹配后打印一行。例如,将此文件作为输入: admin: users: - user1 - user2 read_only: users: - user3 write_only: users: - user4 access_only: users: - user5 - user6 …我需要将此作为输出: admin: users: NEW USER - user
sed
或awk
命令在bash中的多行匹配后打印一行。例如,将此文件作为输入:
admin:
users:
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
…我需要将此作为输出:
admin:
users:
NEW USER
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
正则表达式应该匹配前两行admin:users:
,然后追加newuser
行
如何做到这一点?我应该使用sed还是awk?怎样
也谢谢你。它是YAML,所以将其解析为YAML
#!/usr/bin/env perl
use strict;
use warnings;
use YAML;
use Data::Dumper;
my $stuff = Load ( do { local $/; <DATA> } );
print Dumper $stuff;
print $stuff->{admin}{users}[0],"\n";
print "List:\n";
print join "\n", @{$stuff->{admin}{users}};
__DATA__
admin:
users:
- user1
- user2
#/usr/bin/env perl
严格使用;
使用警告;
使用YAML;
使用数据::转储程序;
my$stuff=Load(do{local$/;});
打印转储程序$stuff;
打印$stuff->{admin}{users}[0],“\n”;
打印“列表:\n”;
打印join“\n”@{$stuff->{admin}{users};
__资料__
管理员:
用户:
-用户1
-用户2
鉴于您已将问题更新为“向admin users节添加新用户”,我的答案已更改,但仍然是“使用perl”:
#!/usr/bin/env perl
use strict;
use warnings;
use YAML::Syck;
use Data::Dumper;
$YAML::Syck::SortKeys = 1;
my $stuff = Load ( do { local $/; <DATA> } );
print Dumper $stuff;
push @{$stuff->{admin}{users}}, "new username";
print Dumper $stuff;
print Dump \$stuff;
__DATA__
admin:
users:
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
#/usr/bin/env perl
严格使用;
使用警告;
使用YAML::Syck;
使用数据::转储程序;
$YAML::Syck::SortKeys=1;
my$stuff=Load(do{local$/;});
打印转储程序$stuff;
push@{$stuff->{admin}{users}},“新用户名”;
打印转储程序$stuff;
打印转储\$stuff;
__资料__
管理员:
用户:
-用户1
-用户2
只读:
用户:
-用户3
只写以下内容:
用户:
-用户4
仅限访问单元:
用户:
-用户5
-用户6
您可以将此设置为:
perl -0777 -MYAML -e '$s = Load(<>);unshift @{$s->{admin}{users}}, "new username"; print Dump $s;'
perl-0777-MYAML-e'$s=Load();unshift@{$s->{admin}{users}},“新用户名”;打印转储$s;'
这将从标准输入中读取数据,进行转换并输出有效的YAMLunshift
将在数组的开头插入用户名-我通常使用push
将其插入到数组的末尾
注意-我在上一个示例中使用了
YAML::Syck
,因为它会对输出进行排序 都不是。它是YAML,所以将其解析为YAML
#!/usr/bin/env perl
use strict;
use warnings;
use YAML;
use Data::Dumper;
my $stuff = Load ( do { local $/; <DATA> } );
print Dumper $stuff;
print $stuff->{admin}{users}[0],"\n";
print "List:\n";
print join "\n", @{$stuff->{admin}{users}};
__DATA__
admin:
users:
- user1
- user2
#/usr/bin/env perl
严格使用;
使用警告;
使用YAML;
使用数据::转储程序;
my$stuff=Load(do{local$/;});
打印转储程序$stuff;
打印$stuff->{admin}{users}[0],“\n”;
打印“列表:\n”;
打印join“\n”@{$stuff->{admin}{users};
__资料__
管理员:
用户:
-用户1
-用户2
鉴于您已将问题更新为“向admin users节添加新用户”,我的答案已更改,但仍然是“使用perl”:
#!/usr/bin/env perl
use strict;
use warnings;
use YAML::Syck;
use Data::Dumper;
$YAML::Syck::SortKeys = 1;
my $stuff = Load ( do { local $/; <DATA> } );
print Dumper $stuff;
push @{$stuff->{admin}{users}}, "new username";
print Dumper $stuff;
print Dump \$stuff;
__DATA__
admin:
users:
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
#/usr/bin/env perl
严格使用;
使用警告;
使用YAML::Syck;
使用数据::转储程序;
$YAML::Syck::SortKeys=1;
my$stuff=Load(do{local$/;});
打印转储程序$stuff;
push@{$stuff->{admin}{users}},“新用户名”;
打印转储程序$stuff;
打印转储\$stuff;
__资料__
管理员:
用户:
-用户1
-用户2
只读:
用户:
-用户3
只写以下内容:
用户:
-用户4
仅限访问单元:
用户:
-用户5
-用户6
您可以将此设置为:
perl -0777 -MYAML -e '$s = Load(<>);unshift @{$s->{admin}{users}}, "new username"; print Dump $s;'
perl-0777-MYAML-e'$s=Load();unshift@{$s->{admin}{users}},“新用户名”;打印转储$s;'
这将从标准输入中读取数据,进行转换并输出有效的YAMLunshift
将在数组的开头插入用户名-我通常使用push
将其插入到数组的末尾
注意-我在上一个示例中使用了
YAML::Syck
,因为它会对输出进行排序 sed用于单个行上的简单替换,仅此而已。对于其他任何东西,您都应该使用awk,以实现软件的简单性、清晰性、效率、健壮性和其他最理想的属性
对于多字符RS和gensub(),使用GNU awk:
sed用于对单个行进行简单替换,仅此而已。对于其他任何东西,您都应该使用awk,以实现软件的简单性、清晰性、效率、健壮性和其他最理想的属性 对于多字符RS和gensub(),使用GNU awk: 如果您在Unix(或其他不使用回车符的环境)中工作,可以通过临时替换新行来使用sed:
cat file | tr '\n' '\r' | sed "s/admin:\r users:/admin:\r users:\r NEW LINE/g" | tr '\r' '\n'
诚然,它比上面的awk解决方案更具黑客性,但为那些想知道如何轻松使用sed的人添加了这一点。如果您在Unix(或其他不使用回车符的环境)中工作,您可以通过临时替换新行来使用sed:
cat file | tr '\n' '\r' | sed "s/admin:\r users:/admin:\r users:\r NEW LINE/g" | tr '\r' '\n'
诚然,它比上面的awk解决方案更具黑客性,但为那些想知道如何轻松使用sed的人添加了这一点。awk解决方案:
awk '/^admin/{ n=NR+2 }NR==n{ sp=substr($0,1,index($0,"-")-1);
printf "%s\n%s\n",sp"NEW USER",$0; next }1' file
输出:
admin:
users:
NEW USER
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
awk解决方案:
awk '/^admin/{ n=NR+2 }NR==n{ sp=substr($0,1,index($0,"-")-1);
printf "%s\n%s\n",sp"NEW USER",$0; next }1' file
输出:
admin:
users:
NEW USER
- user1
- user2
read_only:
users:
- user3
write_only:
users:
- user4
access_only:
users:
- user5
- user6
使用sed
在/^[a-z\+://
和/^$/
之间划界块,以便可以在一个块中执行somme进程:
sed -e $'/^admin:/,/^$/{/users:/a\ NewUser\n}'
这可以写成:
NEWUSER="user2017"
sed -e "/^admin:/,/^$/{
/users:/a\ - $NEWUSER
}"
(通过使用双引号,我可以使用命令行或脚本中的变量)
这将导致:
admin:
users:
- user2017
- user1
- user2
read_only:
users:
- user3
...
或纯。。。
可通过以下方式使用:
myadduser NewAdminUser <file.txt
admin:
users:
- NewAdminUser
- user1
- user2
read_only:
users:
- user3
...
但是请,
读
使用原型或类似于使用最终编程的原型,您可能会找到合适的库
也可以在中使用这些库中的任何一个
第一个管理员用户
perl -MYAML -E 'undef$/;$s = Load(<>);say@{$s->{admin}->{users}}[0];'
perl-MYAML-E'unde$/$s=荷载();说@{$s->{admin}->{users}}[0];'
管理员用户数
perl -MYAML -E 'undef$/;$s = Load(<>);say scalar@{$s->{admin}->{users}};'
perl-MYAML-E'unde$/$s=荷载();说标量@{$s->{admin}->{users}};'
带有sed
在/^[a-z\+://
和/^$/
之间划界块,以便可以在一个块中执行somme进程:
sed -e $'/^admin:/,/^$/{/users:/a\ NewUser\n}'
这可以写成:
NEWUSER="user2017"
sed -e "/^admin:/,/^$/{
/users:/a\ - $NEWUSER
}"
(通过使用双引号,我可以使用命令行或脚本中的变量)
这将导致:
admin:
users:
- user2017
- user1
- user2
read_only:
users:
- user3
...
或纯。。。
可通过以下方式使用:
myadduser NewAdminUser <file.txt
admin:
users:
- NewAdminUser
- user1
- user2
read_only:
users:
- user3
...
但是请,
读
使用原型或类似于使用最终编程的原型,您可能会找到合适的库
也可以在中使用这些库中的任何一个
第一个管理员用户
perl -MYAML -E 'undef$/;$s = Load(<>);say@{$s->{admin}->{users}}[0];'
perl-MYAML-E'unde$/$s=荷载();说@{$s->{admin}->{users}}[0];'
管理员用户数
perl -MYAML -E 'undef$/;$s = Load(<>);say scalar@{$s->{admin}->{users}};'
perl-MYAML-E'unde$/$s=荷载();说标量@{$s->{admin}->{users}};'
这可能适合您(GNU-sed):
如果该行不包含admin:
bail out。