>

이것이 저의 지식을 넘어 서기 때문에 도움을 요청하고 싶습니다. 검색을 시도하고 두 파일 사이를 바꾸려고합니다. 지금까지 모든 특정 문자열 TerminationDate *를 파일 1에서 분리하는 코드를 작성했습니다. 그러나 다른 파일에서 대체 파일을 검색하고 첫 번째 일치 항목 아래 2 줄에있는 문자열을 반환하는 것은 저에게 블랙홀입니다.

작업 할 파일 :

<올>
  • 검색하여 추가 처리 할 필터링 된 데이터를 포함 이 파일 내의 문자열에 대해서는 두 번째 파일에서 대체하십시오.
  • 첫 번째 파일에서 문자열을 찾을 거대한 파일;
  • 하나의 열로 정렬 된 첫 번째 파일에서만 필터링 된 문자열을 포함합니다.
  • 목표는 세 번째 파일의 문자열을 두 번째 문자열로 바꾸고 첫 번째 파일을 이러한 새 데이터로 다시 작성하는 것입니다. 예를 들어이 문자열 TerminationDate1은 파일 1의 날짜 2015/05/25로 바뀝니다.

    첫 번째 파일은 다음과 같습니다.

    config vdom
    edit vdom_1
    config firewall policy
        edit 123
            set uuid xxxxxxxxxxxxxxx
            set srcintf "xxxxx"
            set dstintf "xxxxx"
            set srcaddr "xxxxx"
            set dstaddr "xxxxx"
            set action accept
            set schedule "TerminationDate1" <---
            set service "xxx"
            set logtraffic all
            set comments "xxxxx"
    and so on
    
    

    두 번째 파일의 일부는 다음과 같습니다.

    config firewall schedule onetime
        edit "TerminationDate1"
            set start 12:01 2014/04/24
            set end 12:01 2015/05/25
            set color 0
            set expiration-days 4
    and so on
    
    

    그리고 내가 마지막으로 생성 한 것은 필터링 된 결과가있는 하나의 열을 포함합니다. 두 번째 열에는 두 번째 파일의 해당 문자열이 포함될 수 있습니다.

    TerminationDate1
    TerminationDate2
    TerminationDate3
    and so on
    
    

    첫 번째 논리 부분의 끝.

    두 번째 : 이제 문자열을 일반 날짜로 바꾸면 "if"또는 "variable"저장 메커니즘을 사용하여 데이터를 사람이 읽을 수있는 CSV 형식으로 저장하는 데 어려움을 겪고 있습니다. 입력 파일과 같은 형식은 다음과 같습니다. multiple vdom_1,2;섹션 편집 및 각각에 대한 몇 가지 값. 예를 들면 다음과 같습니다.

    config vdom
    edit vdom_1
    config firewall policy
        edit 123
            set srcaddr "1.1.1.1"
            set dstaddr "2.2.2.2"
            set action accept
            set schedule "2015" <---
            set service "aa"
        edit 456
            set srcaddr "1.1.1.1"
            set dstaddr "2.2.2.2"
            set action accept
            set schedule "2016" <---
            set service "bb"
    edit vdom_2
        edit abc
            set srcaddr "1.1.1.1"
            set dstaddr "2.2.2.2"
            set action accept
            set schedule "2017 <---
            set service "cc"
        edit def
            set srcaddr "1.1.1.1"
            set dstaddr "2.2.2.2"
            set action accept
            set schedule "2018" <---
            set service "dd"
    
    

    내가 놀고있는 코드는

    open my $in_mod,'<', 'inputfile.cfg' or die;
    open my $out_csv,'>', 'outputfile.csv' or die;
    select $out_csv;
        while (my $fh = <$in_mod>){
            chomp $fh;
            if (/^edit (.*)/) {
        $name=$1;
        }
        if (/    edit (.*)/) {
        $maps{$name}=$1;               
        }
        print "$maps";
            ($VDOM) = $fh =~ /^edit (.*)/g;
            ($ID) = $fh =~ /    edit (.*)/g;
            ($SRC) = $fh =~ /        set srcaddr "(.*)"/g;
            ($DST) = $fh =~ /        set dstaddr "(.*)"/g;
            ($Sched) = $fh =~ /        set schedule "(.*)"/g;
            ($Serv) = $fh =~ /        set service "(.*)"/g;
        print "$VDOM,$ID,$SRC,$DST,$Sched,$Serv\n";
        }
    close $in_mod;
    close $out_csv;
    
    

    그러나 내가 찾고있는 출력 형식을 수행하고 있지 않습니다. 내 목표는 아래에 있습니다 :-여기에서 더 이해하기 쉽게 쉼표를 공백으로 바꿨습니다.

    vdom_1  123 1.1.1.1 2.2.2.2 2015    aa
            456 1.1.1.1 2.2.2.2 2016    bb
    vdom_2  abc 1.1.1.1 2.2.2.2 2017    cc
            def 1.1.1.1 2.2.2.2 2018    dd
    
    

    • 답변 # 1

      이 작업을 몇 단계로 나눕니다.

      <올>

      을 만들다 hash ( %maps 예) 먼저, 다음에 대한 매핑을 포함합니다. TerminationDate1 ~로 date 값. 내 예에서는 정규식을 사용하여 정보를 추출했습니다. 아래 두 줄의 내용이 필요한 정보인지 항상 확인해야하기 때문에 "아래 2 줄 읽기"보다 낫습니다. 확인하는 방법은 일반적으로 정규식입니다.

      첫 번째 파일을 한 줄씩 살펴보고 각 줄의 내용을 바꾸려면 대용을 사용하십시오. 당신은 가지고 있기 때문에 hash 첫 번째 단계에서, 당신은 또한 각 라인에서 맵을 반복하고 각각을 사용하여 대체를 시도해야합니다 key .

      선택적으로 필터링 된 목록이 있다고 언급했는데, 예제에서는 사용하지 않고 필요한 경우 목록을 사용하여 %maps

      참조 : https://perldoc.perl.org/perlre.html

      암호:

      #!/usr/bin/env perl
      use strict;
      use warnings;
      my %maps;
      open my $in_2nd,'<', '2nd.txt' or die;
      my $name="";
      while (<$in_2nd>){
          chomp;
          if (/edit "(\w+)"/){
              $name=$1;
           }
           if (/set end (.*)$/){
              $maps{$name}=$1;
           }
      }
      close $in_2nd;
      warn(%maps); # check if the maps are correct
      open my $in_1st,'<', '1st.txt' or die;
      while(<$in_1st>){
          for my $k (keys %maps){
              s/$k/$maps{$k}/;
          }
          print;
      }
      close $in_1st;
      
      

      결과:

      config vdom
      edit vdom_1
      config firewall policy
          edit 123
              set uuid xxxxxxxxxxxxxxx
              set srcintf "xxxxx"
              set dstintf "xxxxx"
              set srcaddr "xxxxx"
              set dstaddr "xxxxx"
              set action accept
              set schedule "12:01 2015/05/25"
              set service "xxx"
              set logtraffic all
              set comments "xxxxx"
      
      

    관련 자료

  • 이전 c - 16 진수 형식으로 플로트 받기
  • 다음 tensorflow - Lenet5와 유사한 아키텍처를 사용하여 '101 개 오브젝트 범주'데이터를 분류 할 때 예상보다 높은 정확도 확보