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'로 바꾸고 싶습니다. 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위에서 사용한 것입니다.

관련 정보