인덱스가 숫자가 아닌 awk를 사용하여 이전 인덱스에서 빼기

인덱스가 숫자가 아닌 awk를 사용하여 이전 인덱스에서 빼기

이전 값에서 값을 빼고 싶은데 조건이 충족되어야 합니다.

문서:

2022-02-01 01:00:00|abc|2001|5
2022-02-01 01:00:00|abc|2002|10
2022-02-01 01:01:00|abc|2001|6
2022-02-01 01:01:00|abc|2002|11
2022-02-01 01:02:00|abc|2001|10
2022-02-01 01:02:00|abc|2002|11
2022-02-01 01:02:00|abc|2003|2

원하는 출력:

2022-02-01 01:00:00|abc|2001|5
2022-02-01 01:00:00|abc|2002|10
2022-02-01 01:01:00|abc|2001|1
2022-02-01 01:01:00|abc|2002|1
2022-02-01 01:02:00|abc|2001|4
2022-02-01 01:02:00|abc|2002|0
2022-02-01 01:02:00|abc|2003|2

awk를 사용해 보았지만 값을 빼기 위해 이전 인덱스에 접근할 수 없습니다.

awk -F"|" 'BEGIN{OFS="|"}{a[$1,$2,$3]=$4}END{for (i in a) print i, a[i]-a[i-1] }' file

답변1

당신이하고 싶은 일은 다음과 같은 것 같습니다 :

awk -v FS="|" -v OFS="|" '{ a=$4;if($3 in dict)$4-=dict[$3]; dict[$3]=a}1' file

나는 associative arrays키로 가지고 있는 연도를 저장하기 위해 awk를 사용하고 있으며 그 값은 마지막 열이 될 것입니다. 예를 들어 배열은 다음과 같아야 합니다.

dict[2001] = "4th column"
dict[2002] = "4th column"
dict[2003] = "4th column"
....

따라서 dict 키/값은 다음과 같습니다.

dict[2001] = "5"
dict[2002] = "10"
dict[2001] = "6"
dict[2002] = "11"
dict[2001] = "10"
dict[2002] = "11"
dict[2003] = "2" # this never changes because you have only one 2003 as year.

따라서 awk 코드를 사용하면 현재 주요 연도에서 네 번째 열에 저장된 마지막 값을 뺄 a=$4;if($3 in dict)$4-=dict[$3]; dict[$3]=a수 있습니다 .dict3달러는 연도입니다그리고$4는 인덱스/값입니다.


귀하의 의견에서 말씀하신 것처럼 keys연관 배열은 abc|year. 그렇다면 다음을 사용해야 합니다.

awk -F'|' -v OFS='|' '{a=$4; if(($2,$3) in dict)$4-=dict[$2,$3]; dict[$2,$3]=a }1' file

답변2

사용 miller:

mlr --nidx --fs '|' put '$delta = is_present(@last[$3]) ? $4 - @last[$3]  : $4; @last[$3] = $4; unset $4' file

이 명령에서는 네 번째 필드가 @last세 번째 필드의 인덱스에 저장됩니다. 그것이 사실 is_present인지 확인한 다음 @last[$3](즉, 현재 레코드의 세 번째 필드에 인덱스 변수가 있음) 두 값의 차이를 인쇄합니다. 그렇지 않으면 네 번째 필드를 인쇄합니다.

마지막 네 번째 필드는 설정되지 않았습니다.

첫 번째 값이 필요하지 않은 경우 다음 값을 사용할 수 있습니다.

 mlr --nidx --fs '|' step -g 3 -a delta -f 4 file

관련 정보