bash 用于定位变量并替换下面几行引号之间的字符串的脚本
bash script to locate variable and replace string between quotes a few lines below
我有一个纯文本文件 "user database",其中包含一遍又一遍重复的相同 4 行。每4行"array"代表用户数据库中的一个用户如下:
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordXYZ',
comment => 'Mickey Mouse';
AX112233
始终是唯一值。我需要一个脚本,当给定 2 个值时,即唯一用户名 AX112233
和新密码 AX112233:passwordABC
,将能够在文件中找到唯一用户名并替换引号之间的密码值 3 行。
因此在收到输入后 AX112233:passwordABC
将按如下方式更改数组:
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordABC',
comment => 'Mickey Mouse';
最好是用 bash/sed/awk/
写的东西,但不一定是。任何帮助将不胜感激。
到目前为止,我所知道的是这个 Perl 脚本可以正常工作。我相信这对于 Perl 专家来说是一个简单的问题,而我不是。该脚本的问题是初始密码未知,因此脚本需要替换 password =>
之后单引号之间的任何内容
$ cat input.txt
AX112233':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
$ perl -pe '++$x and next if /AX112233/; $x-- and s/passwordXYZ/passwordABC/ if $x' input.txt
AX112233':
password => 'passwordABC',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
上面的另一个问题是行密码必须是 AX11223
下面的下一行。如果该行是下面的 3 行,例如
怎么办?
AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordABC',
comment => 'Mickey Mouse';
可以轻松地对 Perl 脚本进行简单的改编:
perl -pe '++$x and next if /AX112233/;
/password\s*=>/ and $x-- and '"s/'[^']*'/'passwordABC'/"' if $x' input.txt
这里有一些 shell 诡计,而不是真正的 Perl 魔法。第一行与您所拥有的相同。第二行查找包含 password =>
的行,然后使用一些 shell 技巧将单引号更改为双引号('"
,然后包含一个 s///
命令,看起来对于单引号,不是单引号的任意字符序列和另一个单引号,并将其替换为用单引号引起来的密码的新值。 "'
恢复为单引号字符串,以便if $x
不需要反斜杠。有更简洁的方法来做到这一点,但这是您所拥有的的简单变体。
给定这样的输入文件:
'AX112233':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX221133':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
password => 'passwordXYZ',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX113322':
uid => '22044',
password => 'passwordXYZ',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordXYZ',
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse',
password => 'passwordXYZ';
(对于不同的用户 ID 有 2 个条目,并且密码位于匹配用户 ID 之后的第一、第二、第三或第四行)生成:
'AX112233':
password => 'passwordABC',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX221133':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
password => 'passwordABC',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX113322':
uid => '22044',
password => 'passwordXYZ',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordABC',
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse',
password => 'passwordABC';
另一种方法:
user="AX112233"
password="passwordABC"
perl -pe 'if ('"/$user/"') { ++$x; next }
if ($x && '"s/password\s*=>\s*'[^']*'/password => '$password'/"') { $x-- }' input.txt
这将匹配和替换结合在一个操作而不是两个操作中,并使用常规前导 if
而不是尾随 if
条件。它还允许通过 shell 变量指定用户名和新密码。
使用 sed,您可以使用 sed 地址搜索 $username
,并将从该地址找到的下一个密码替换为 $newpass
值:
username="AX112233";
newpass="passwordABC";
sed "/ *'$username'/,/;/{s/^\([ \t]*password => *'\).*/$newpass',/}" file
我有一个纯文本文件 "user database",其中包含一遍又一遍重复的相同 4 行。每4行"array"代表用户数据库中的一个用户如下:
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordXYZ',
comment => 'Mickey Mouse';
AX112233
始终是唯一值。我需要一个脚本,当给定 2 个值时,即唯一用户名 AX112233
和新密码 AX112233:passwordABC
,将能够在文件中找到唯一用户名并替换引号之间的密码值 3 行。
因此在收到输入后 AX112233:passwordABC
将按如下方式更改数组:
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordABC',
comment => 'Mickey Mouse';
最好是用 bash/sed/awk/
写的东西,但不一定是。任何帮助将不胜感激。
到目前为止,我所知道的是这个 Perl 脚本可以正常工作。我相信这对于 Perl 专家来说是一个简单的问题,而我不是。该脚本的问题是初始密码未知,因此脚本需要替换 password =>
$ cat input.txt
AX112233':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
$ perl -pe '++$x and next if /AX112233/; $x-- and s/passwordXYZ/passwordABC/ if $x' input.txt
AX112233':
password => 'passwordABC',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
上面的另一个问题是行密码必须是 AX11223
下面的下一行。如果该行是下面的 3 行,例如
AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordABC',
comment => 'Mickey Mouse';
可以轻松地对 Perl 脚本进行简单的改编:
perl -pe '++$x and next if /AX112233/;
/password\s*=>/ and $x-- and '"s/'[^']*'/'passwordABC'/"' if $x' input.txt
这里有一些 shell 诡计,而不是真正的 Perl 魔法。第一行与您所拥有的相同。第二行查找包含 password =>
的行,然后使用一些 shell 技巧将单引号更改为双引号('"
,然后包含一个 s///
命令,看起来对于单引号,不是单引号的任意字符序列和另一个单引号,并将其替换为用单引号引起来的密码的新值。 "'
恢复为单引号字符串,以便if $x
不需要反斜杠。有更简洁的方法来做到这一点,但这是您所拥有的的简单变体。
给定这样的输入文件:
'AX112233':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX221133':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
password => 'passwordXYZ',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX113322':
uid => '22044',
password => 'passwordXYZ',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordXYZ',
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse',
password => 'passwordXYZ';
(对于不同的用户 ID 有 2 个条目,并且密码位于匹配用户 ID 之后的第一、第二、第三或第四行)生成:
'AX112233':
password => 'passwordABC',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX221133':
password => 'passwordXYZ',
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
password => 'passwordABC',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX113322':
uid => '22044',
password => 'passwordXYZ',
groups => ['grp01'],
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
password => 'passwordABC',
comment => 'Mickey Mouse';
'AX112233':
uid => '22044',
groups => ['grp01'],
comment => 'Mickey Mouse',
password => 'passwordABC';
另一种方法:
user="AX112233"
password="passwordABC"
perl -pe 'if ('"/$user/"') { ++$x; next }
if ($x && '"s/password\s*=>\s*'[^']*'/password => '$password'/"') { $x-- }' input.txt
这将匹配和替换结合在一个操作而不是两个操作中,并使用常规前导 if
而不是尾随 if
条件。它还允许通过 shell 变量指定用户名和新密码。
使用 sed,您可以使用 sed 地址搜索 $username
,并将从该地址找到的下一个密码替换为 $newpass
值:
username="AX112233";
newpass="passwordABC";
sed "/ *'$username'/,/;/{s/^\([ \t]*password => *'\).*/$newpass',/}" file