私は最初に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'に置き換えたいと思います。 10日、7日5日、7日30日....
これを行う最良の方法は何ですか?これを行うには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; }
(注:myにはstrings.txt
3つの値しか含まれていないため、S0、S1、S2のみが変更されます。パラメータの他のすべての値は変更されません。)
%params
これにより、パラメータファイルのすべての値を含むハッシュ()が生成されます。次に、"strings"ファイルから%paramsの各要素の新しい値セットを読み込みます。最後に、%paramsハッシュを自然にソートされた順序(読み取りと同じ形式)で印刷します。
読み取るファイルは、コマンドラインでパラメータ1と2で指定できます。デフォルトはとparams.txt
ですstrings.txt
。
スクリプトは、文字列ファイルの各行に更新された値があると仮定します。スペースまたはカンマで区切られている場合は、パラメータファイルを読み取るために使用されたコードと同様に、各入力行を配列に分割して繰り返すことができます。上記で使用した行数ではなく、各フィールドを使用するときにフィールド数を追跡する必要があります。
fmt
スクリプトは、またはなどのツールを使用して簡単に達成できるため、長い行を折り返すことはありませんpar
。たとえば、上記で./change-params.pl | fmt
使用したものです。