쉘 스크립트 작성 도움말

쉘 스크립트 작성 도움말

저는 심층적인 쉘 스크립팅 감정가가 아닙니다. 기본 사항을 알고 있으며 내 문제에 대한 제안에 열려 있습니다. 하루 24시간 실행되는 스크립트를 작성해야 하지만 솔직히 어디서부터 시작해야 할지조차 모릅니다. 다음 상황에 따라 이 스크립트를 어떻게 조립하는지 아시나요?

다음과 같은 시나리오가 있습니다. 예제 1(오늘 일어난 일)과 예제 2(예상 결과)

실시예 1

#가격_알림_제품ABC
가격: 0.006813
변경: +1.6%
카운트 수: 1

#가격_알림_제품ABC
가격: 0.006969
변경: +2.3%
카운트 수: 2

#가격_알림_제품ABC
가격: 0.007060
변경: +1.3%
카운트 수: 3

#가격_알림_제품ABC
가격: 0.007300
변경: +3.4%
카운트 수: 4

#가격_알림_제품ABC
가격: 0.007453
변경: +2.1%
카운트 수: 5

실시예 2

#가격_알림_제품ABC
가격: 0.006813
변경: +1.6%
카운트 수: 1

#가격_알림_제품ABC
가격: 0.006969
변경: +3.9%
카운트 수: 2

#가격_알림_제품ABC
가격: 0.007060
변경: +5.2%
카운트 수: 3

#가격_알림_제품ABC
가격: 0.007300
변화: +8.6%
카운트 수: 4

#가격_알림_제품ABC
가격: 0.007453
변화: +10.7%
카운트 수: 5

필요하다:

1- #Price_Notification_ProductABC 항목은 고정된 항목이 아니며 검색에서 여러 제품(Price_Notification_ProductABC, #Price_Notification_ProductXYZ, #Price_Notification_Product123 등)이 반환될 수 있으므로 이 항목이 작동하려면 grep을 사용하여 항목을 일치시켜야 한다고 생각합니다. 이 항목에 대한 알림을 받았습니다

2- 가격 항목에는 사전 정의된 소수 자릿수가 없으며 가격: 0.006813 가격: 1.256 가격: 524.354 등의 형식일 수 있으며 동적입니다.

3- 항목 변경은 설명하기 가장 복잡합니다. 예 1에 표시된 것처럼 알림은 항상 소수인 숫자를 포함하는 백분율을 반환합니다.

  • 예제 2와 같이 합계를 점진적으로 계산하는 필터를 원합니다.
  • 이 증분 합계는 항상 이전 알림의 비율 + 현재 알림의 비율을 더해야 합니다.
  • 그러나 여기에는 몇 가지 조건이 있습니다. 현재 알림의 가격 항목 값은 항상 이전 알림의 값보다 커야 합니다. 이 조건이 충족되지 않으면 알림 합계/퍼센트를 포함하는 루프/필터를 재설정해야 합니다. , 이에 따라 새로운 알림 기간이 시작됩니다.

4- 프로젝트 계산, 계산도 동적이고 매 시간마다 항상 0으로 재설정되기 때문에 이 프로젝트를 어떻게 처리해야 할지 잘 모르겠습니다. 하지만 이 프로젝트를 처리하는 방법에 대한 제안을 환영합니다.


나는 이 방법으로 이 정보를 얻고 있으며 이에 대해 내가 할 수 있는 일은 아무것도 없다는 점에 유의하십시오. 나는 받은 정보를 기반으로 나에게 도움이 될 스크립트를 작성하려고 노력하고 있습니다.

또한 두 가지 기준/조건을 해결해야 합니다. 이 두 조건 중 하나가 존재하면 증가/증가 백분율 계산을 재설정하여 새 루프를 시작해야 합니다.

1- 백분율은 증분식으로 계산되어야 합니다. 한 알림과 다른 알림 사이의 0~최대 30분 범위에서 31분부터 시작하여 백분율의 증분 계산을 재설정/다시 시작하여 새 알림 계산을 시작해야 합니다. 주기

2- 가격 항목에서 받은 마지막 알림에는 이전 알림보다 낮은 값이 포함될 수 없습니다. 예를 들어 새 알림을 3개 더 받았습니다(개수: 6, 개수: 7, 개수: 8).

#가격_알림_제품ABC
가격: 0.007023
변경: +1.8%
카운트 수: 6

#가격_알림_제품ABC
가격: 0.007184
변경: +2.3%
카운트 수: 7

#가격_알림_제품ABC
가격: 0.007328
변경: +3.3%
계산 수량: 8

이 예에서는 Price: 0.007023알림 개수가 6인 항목이 Price: 0.007453알림 개수가 5인 이전 항목보다 값이 낮으므로 이전에 수행한 모든 계산을 0으로 설정/다시 시작하는 새 루프를 시작해야 합니다.

다음과 같아야 합니다.

#가격_알림_제품ABC
가격: 0.007023
변경: +1.80%
카운트 수: 6

#가격_알림_제품ABC
가격: 0.007184
변경: +4.10%
카운트 수: 7

#가격_알림_제품ABC
가격: 0.007328
변경: +7.40%
계산 수량: 8

다른 상황에서 이 문제를 해결하기 위한 제안 사항이 있습니까?

감사해요!

답변1

awk이것은 보기만큼 어렵지 않으며 또는 에서 수행하는 것이 매우 쉽습니다 perl.

펄 사용:

$ perl -lpe 'if (/^#Price_Notification_Product/) {
               $prod = $_;
             } elsif (/^change: ([^%]*)%/) {
               $products{$prod} += $1;
               $_ = "change: +$products{$prod}%";
             }' input.txt 
#Price_Notification_ProductABC
Price: 0.006813
change: +1.6%
Count Number: 1

#Price_Notification_ProductABC
Price: 0.006969
change: +3.9%
Count Number: 2

#Price_Notification_ProductABC
Price: 0.007060
change: +5.2%
Count Number: 3

#Price_Notification_ProductABC
Price: 0.007300
change: +8.6%
Count Number: 4

#Price_Notification_ProductABC
Price: 0.007453
change: +10.7%
Count Number: 5
  • 줄 종결자의 자동 처리를 켜는 Perl 옵션 -l(예: 입력에서 개행 문자를 제거하고 이를 printby 문의 출력에 추가)
  • -p옵션을 사용하면 sed처럼 작동합니다(즉, 각 입력 줄을 읽고 처리 후에 자동으로 인쇄합니다).
  • -e다음 인수가 실행될 스크립트임을 Perl에 알립니다.

스크립트는 각 입력 줄을 읽고 줄이 "#Price_Notification_Product"로 시작하는 경우 현재 줄을 변수에 저장합니다 $prod.

그렇지 않고 행이 "change:"로 시작하면 다음과 같습니다.

  • 정규식 캡처를 사용하여 변경된 값을 추출하고 해당 값을 명명된 해시("연관 배열"이라고도 함)에 추가합니다 %products. 해시의 키는 제품 이름( $prod)입니다.

    #Price_Notification_Product...각 제품의 행이 고유하고 일관성이 있는 한 입력에서 원하는 수의 제품 이름을 처리할 수 있도록 해싱을 사용합니다 . 각 제품 이름의 누적 합계는 독립적으로 추적됩니다.

  • $_이 제품의 현재 누적 합계를 갖도록 현재 행(변수)을 변경합니다 .

    그런데 "change:" 줄에 소수점 앞이나 뒤에 고정된 자릿수를 지정하려면 를 사용하면 됩니다 sprintf. 예를 들어 $_ = "change...."다음과 같이 줄을 변경할 수 있습니다.

               $_ = sprintf("change: %7.2f%%", $products{$prod});
               s/(\d)/+$1/;
    

    그러면 아래와 같이 "change" 줄이 출력됩니다.

    change:   +1.60%
    change:   +3.90%
    change:   +5.20%
    change:   +8.60%
    change:  +10.70%
    

모든 입력 행은 수정 여부에 관계없이 인쇄됩니다.

입력은 파일( input.txt제가 사용한 것과 같은)이나 표준 입력(예: 파이프와 같은 tail -f)에서 올 수 있습니다.


그런데, 제품 수가 0으로 재설정되면 제품의 누적 합계를 0으로 재설정하고 싶을 수도 있다는 생각이 들었습니다. 이 경우 마지막 줄을 변경하십시오.

         }' input.txt 

이와 관련하여:

         } elsif (/^Count Number: 0$/) {
           $products{$prod} = 0;
         }' input.txt 

독립형 스크립트와 동일:

#!/usr/bin/perl -lp

if (/^#Price_Notification_Product/) {
  $prod = $_;
} elsif (/^change: ([^%]*)%/) {
  $products{$prod} += $1;
  $_ = "change: +$products{$prod}%";
}

#!Perl 인터프리터가 다른 위치에 있는 경우 올바른 전체 경로를 참조하도록 행을 조정해야 합니다 .

예를 들어 다음과 같은 이름으로 저장하고 다음 을 사용하여 실행 가능 ./script.pl하게 만듭니다 chmod +x script.pl.

$ ./script.pl input.txt

또는

$ perl -lp ./script.pl input.txt

awk 버전인 Perl 버전을 직접 번역했지만 각 "change:" 줄 의 두 번째 필드에서 앰퍼샌드를 gsub()제거 해야 합니다.+%

$ awk '
/^#Price_Notification_Product/ {
  prod = $0;
}
/^change: / {
  gsub(/[+%]/,"",$2);
  products[prod] += $2;
  $2 = "+" products[prod] "%"
}
1' input.txt

awk 스크립트의 마지막 줄은 1오타가 아닙니다. 이는 수정 여부에 관계없이 항상 현재 줄을 인쇄하도록 awk에 지시합니다(awk 스크립트는 기본적으로 일련의 PATTERN ACTION 규칙입니다. PATTERN이 true로 평가되면 ACTION이 1평가됩니다 . true로 설정하고 기본 작업은 {print})

관련 정보