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

标签 linux bash perl sed substitution

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

   '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 变量指定用户名和新密码。

关于linux - bash 脚本来定位变量并替换下面几行引号之间的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36463671/

相关文章:

perl - 如何在 Perl 的 Wasm::Wasmtime 中使用二进制 WASM 文件?

perl - LWP UserAgent 帖子 @list

linux - 如何在mongodb中将数据库从一台服务器复制到另一台服务器

java执行linux命令

c - 如何在运行时在 c 中启动一个进程

bash - 匹配带有空格的字符串并替换为另一个类似的带有空格的字符串

linux - 使用shell脚本重命名目录及其子目录中的文件夹?

linux - 如何指定在 CentOS 上使用哪个版本的 perl

c - 是否可以将两个以上的标准流连接到 Linux 中的终端?

c++ - 关于 linux 中的动态缩放,程序在时钟周期中的意外执行时间