이것은 간단한 질문이므로 미리 사과드립니다. 그래도 그렇죠.
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
편집 3: 그러나 전자는 첫 번째 줄에 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개를 이동 변수로 바꿔야 합니다. 사용법에 주의해야 합니다 gawk
. 내가 아는 한 정규식은 awk
정규식에서 그룹을 추출할 수 없습니다.
이것은 무엇을 합니까? 일치를 수행하고 정규 표현식을 사용하여 $0
결과를 입력하고 다음과 일치합니다. - 0개 이상의 숫자가 아닌 문자를 첫 번째 배열 인덱스에 넣은 다음(대괄호는 소위 그룹화를 담당함) 비숫자와 일치합니다. -길이가 0인 숫자(그리고 이를 배열의 두 번째 요소로 만듭니다).ary
/([^0-9]*)([0-9]+)/
([^0-9]*)
([0-9]+)
물론 이는 일부 오류 검사, 일치를 위한 특수 사례 등을 통해 더 복잡하게 수행될 수 있습니다. 하지만 이 문제는 직접 탐색해 보시기 바랍니다(예: 정규 표현식).