이동된 열이 있는 누적 합계

이동된 열이 있는 누적 합계

이것이 쉬운 문제라고 확신하므로 미리 사과드립니다. 그럼에도 불구하고 여기로 갑니다.

cat blah.txt
aa+2
bb+4
cc+10
dd+31

blah.txt를 처리하여 다음을 생성하고 싶습니다.

aa+0
bb+2
cc+6
dd+16

여기서의 개념은 첫 번째 열이 노래 목록이고 두 번째 열이 시작 시간일 수 있다는 것입니다.

내 직감은 awk를 사용하여 이 작업을 수행하는 것이었습니다. 나는 $1과 총합 $2를 저장하는 숫자 인덱스가 있는 두 개의 배열을 생각했습니다. 내 생각은 누계의 숫자 인덱스를 1씩 이동하는 것이었습니다.

tail -r blah.txt | 
awk -F "+" '{ for(i=0;i<=NR;i++) arr[i+1]+=$2; farr[i]=$1 } END 
{ for(i=NR+1;i>1;i--) {if (i==NR) {print farr[NR] FS 0 } 
else { print farr[i] FS arr[i]}}}'

이는 간결하지 않으며 더 이상 작동하지 않습니다. 무엇보다 어레이 제작 실패에 당황스럽습니다.

어쨌든, 어떤 친절한 사람이 나를 이 불행에서 구해 줄 수 있을까요?

답변1

여기 있습니다:

$ awk -F+ '{sum+=$2;printf("%s+%d\n",$1,sum-$2);}' blah.txt
aa+0
bb+2
cc+6
dd+16

Edit1: Sukminder 덕분에 약간 더 간단한 방법이 있습니다.

$ awk -F+ '{printf("%s+%d\n",$1,sum);sum+=$2}' blah.txt

Edit2: Bernhard 덕분에 약간 더 간결해졌습니다.

$ awk -F+ '{print $1,sum;sum+=$2}' OFS="+" blah.txt

Edit3: 그러나 전자는 첫 번째 줄에 0을 표시하지 않으므로 여기에 Tom의 질문에 대답하는 더 짧은 방법을 보여주는 수정되고 다소 압축된 버전이 있습니다(새로운 의견이 더 나은 것을 제안할 때까지).

$ awk -F+ '{print$1,s+0;s+=$2}' OFS=+ blah.txt

답변2

이를 수행하는 가장 좋은 방법은 정규식을 배우고 사용하는 것입니다. 왜냐하면 앞으로는 그런 종류의 작업을 수행하는 데 많은 어려움을 겪을 수 있기 때문입니다.

cat blah.txt | gawk 'match($0, /([^0-9]*)([0-9]+)/, ary) {print ary[1] ary[2]-2}'

마지막 2개를 Shift 변수로 대체해야 합니다. 의 사용법을 참고해야 합니다 gawk. 내가 아는 한, 정규식은 awk정규식에서 그룹을 추출할 수 없습니다.

이것이 무엇을 하는가? 정규식을 사용하여 에 일치를 $0수행하고 결과를 넣습니다. 이는 다음과 일치합니다 . - 숫자가 아닌 0개 이상의 문자를 첫 번째 배열 인덱스에 넣은 다음(괄호는 그룹화를 담당함) 길이가 0이 아닌 숫자와 일치합니다 . (그리고 그것을 배열의 두 번째 요소로 둡니다).ary/([^0-9]*)([0-9]+)/([^0-9]*)([0-9]+)

물론 이는 일부 오류 검사, 특수한 일치 사례 등과 함께 더 정교하게 만들 수 있습니다. 하지만 이(즉, 정규식)를 직접 탐색해 보시기 바랍니다.

관련 정보