저는 심층적인 쉘 스크립팅 감정가가 아닙니다. 기본 사항을 알고 있으며 내 문제에 대한 제안에 열려 있습니다. 하루 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
(예: 입력에서 개행 문자를 제거하고 이를print
by 문의 출력에 추가) - 이
-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}
)