如何使用 sed 将某些模式替换为 bash 中的字符串列表

如何使用 sed 将某些模式替换为 bash 中的字符串列表

我是 sed 的新手,最近遇到了一些问题,如下所示:

{ parameter S0=7'd0, S1=7'd1, S2=7'd2, S3=7'd3, S4=7'd4,                      
S5=7'd5, S6=7'd6, S7=7'd7, S8=7'd8, S9=7'd9, 
S10=7'd10, S11=7'd11, S12=7'd12, S13=7'd13, S14=7'd14, 
S15=7'd15, S16=7'd16, S17=7'd17, S18=7'd18, S19=7'd19,
S20=7'd20, S21=7'd21, S22=7'd22, S23=7'd23, S24=7'd24,
S25=7'd25, S26=7'd26, S27=7'd27, S28=7'd28, S29=7'd29,
S30=7'd30, S31=7'd31, S32=7'd32, S33=7'd33, S34=7'd34,
S35=7'd35;  }

我有一个像 ['10' '5' '30' ... ] 这样的字符串列表,然后我想匹配模式 7'd0、7'd1、7'd2...,然后将它们替换为 7'd10 , 7'd5, 7'd30 ....

做这个的最好方式是什么?必须使用forloop来做到这一点吗?

答案1

#!/usr/bin/perl

use strict;
use Sort::Naturally;   # CPAN module to perform Natural Sorts.

# should do real option/argument processing here.  this is good enough
# for this example.
my $params  = shift || 'params.txt';
my $strings = shift || 'strings.txt';

my %params=();  # hash to hold each parameter

# read in the parameters file.
open(PARAMS,"<",$params) || die "couldn't open $params: $!";
while(<PARAMS>) {
  # clean up input, discard everything that would complicate splitting
  # into comma-separated fields.
  s/^\s*\{\s*parameter\s+//;
  s/\s*;\s*\}//;
  s/^\s*|\s*$//g;
  s/\s*,$//;   # / this comment fixes stack exchange\'s broken syntax colouring
  chomp;

  # split each input line into an array, with comma as separator
  my @F = split /\s*,\s*/;   # /

  # use each array element to populate the %params hash
  foreach my $f (@F) {
    my ($key,$val) = split /\s*=\s*/, $f;    # /
    $params{$key} = $val;
  };
};
close(PARAMS);

# read in the strings file and apply changes to %params
# this assumes that the strings file contains new values for 
# all paramaters and that they are listed one-per-line in order (0..35)
open(STRING,"<",$strings) || die "couldn't open $strings: $!";
my $lineno = 0;
while(<STRING>) {
  s/^\s*|\s*$//g; # remove leading/trailing whitespace
  s/#.*//;        # ignore comments
  next if (/^$/);

  $params{'S'.$lineno++} = "7'd$_";
};
close(STRING);

# natural-sort %params keys
my @keys = nsort(keys %params);

print '{ parameter ', join(', ', map { $_ = "$_=$params{$_}" } @keys ), "; }\n";

另存为,例如,change-params.pl使可执行文件chmod +x,并运行如下:

$ ./change-params.pl [parameter-file [strings-file]]

输出示例:

$ ./change-params.pl | fmt
{ parameter S0=7'd10, S1=7'd5, S2=7'd30, S3=7'd3, S4=7'd4, S5=7'd5,
S6=7'd6, S7=7'd7, S8=7'd8, S9=7'd9, S10=7'd10, S11=7'd11, S12=7'd12,
S13=7'd13, S14=7'd14, S15=7'd15, S16=7'd16, S17=7'd17, S18=7'd18,
S19=7'd19, S20=7'd20, S21=7'd21, S22=7'd22, S23=7'd23, S24=7'd24,
S25=7'd25, S26=7'd26, S27=7'd27, S28=7'd28, S29=7'd29, S30=7'd30,
S31=7'd31, S32=7'd32, S33=7'd33, S34=7'd34, S35=7'd35; }

(注意:mystrings.txt只包含你提到的3个值,所以它只改变S0、S1和S2。参数中的所有其他值都不变)

这将构造一个散列 ( %params) 以包含参数文件中的所有值。然后它从“strings”文件中读取 %params 的每个元素的一组新值。最后,它以自然排序的顺序打印 %params 哈希值(与读取的格式相同)。

可以在命令行上指定要读取的文件(作为参数 1 和 2)。它们默认为params.txtstrings.txt

该脚本假定字符串文件的每一行都有一个更新值。如果它是空格或逗号分隔的,您可以将每个输入行拆分为一个数组并对其进行迭代,类似于用于读取参数文件的代码。您必须在使用每个字段时跟踪字段计数,而不是上面使用的行计数。

该脚本不会换行长行,因为这可以使用fmt或等工具轻松实现par。例如./change-params.pl | fmt我上面使用的。

相关内容