bash脚本定位变量并替换下面几行引号之间的字符串



我有一个纯文本文件"用户数据库",其中包含重复的相同4行。每个4行"数组"表示用户数据库中的一个用户,如下所示:

   'AX112233':  
      uid      => '22044',  
      groups   => ['grp01'],  
      password =>  'passwordXYZ',  
      comment  => 'Mickey Mouse';  

AX112233始终是一个唯一的值。我需要一个脚本,当给定两个值,即唯一用户名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';

上面的另一个问题是行密码必须是CCD_ 7下面的下一行。如果这条线比低3行怎么办

AX112233':  
      uid      => '22044',  
      groups   => ['grp01'],  
      password =>  'passwordABC',  
      comment  => 'Mickey Mouse';

可以很容易地对Perl脚本进行简单的调整:

perl -pe '++$x and next if /AX112233/;
          /passwords*=>/ and $x-- and '"s/'[^']*'/'passwordABC'/"' if $x' input.txt

这里有一些shell技巧,而不是真正的Perl技巧。第一行和你的一模一样。第二行查找包含password =>的行,然后使用一些shell技巧将单引号改为双引号('",然后包含一个s///命令,该命令查找单引号、非单引号的任意字符序列和另一个单引号,并将其替换为单引号中包含的密码的新值。"'恢复为单引号字符串,这样if $x就不需要反斜杠了e你所拥有的变化。

给定这样的输入文件:

'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/passwords*=>s*'[^']*'/password => '$password'/"') { $x-- }' input.txt

这将匹配和替换组合在一个操作中而不是两个操作中,并使用正则前导if而不是尾随if条件句。它还允许通过shell变量指定用户名和新密码。

使用sed,您可以使用sed地址搜索$username,并将从该地址找到的下一个密码替换为$newpass值:

username="AX112233"; 
newpass="passwordABC";
sed "/ *'$username'/,/;/{s/^([ t]*password => *').*/1$newpass',/}" file

最新更新