이전 행을 기반으로 행 업데이트

이전 행을 기반으로 행 업데이트

awk에 익숙하지 않아서 질문이 있습니다. sar -d 출력으로 생성된 csv 파일을 csv 스타일로 변환했습니다.

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
,iscsi0,0,0.0,0,0,0.0,0.0
,scsi_vhc,0,0.0,0,0,0.0,0.0
,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
,iscsi0,0,0.0,0,0,0.0,0.0
,scsi_vhc,0,0.0,0,0,0.0,0.0
,nfs1,0,0.0,0,0,0.0,0.0

이걸로 변환하고 싶어요

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
12:35:00,iscsi0,0,0.0,0,0,0.0,0.0
12:35:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:35:00,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
12:45:00,iscsi0,0,0.0,0,0,0.0,0.0
12:45:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:45:00,nfs1,0,0.0,0,0,0.0,0.0

시도해 보았지만 awk는 한 줄씩 읽기 때문에 이전 줄의 값을 유지하는 방법을 모르겠습니다. 내가 가진 것이 효과가 있기를 바랍니다. 내가 원하는 결과를 얻으려면 무엇이 필요한지 알아보세요. 나는 awk를 사용해 보았지만 이것이 sed를 사용하거나 사용자 정의 쉘 스크립트를 사용하여 가능해야 한다고 생각합니다(이 부분은 수행하지 않으려고 노력하고 있습니다).

#!/usr/bin/awk -f
BEGIN {
        FS=",";
}
{
        print $1
        if ($1 != "") {
                mydate=$1;
                print $0;
        }
        else {
                print $mydate","$0;
        }
}

Solaris 11.1 시스템을 실행 중입니다.

답변1

입력에 빈 줄이 있는 것처럼 보이기 때문에 시간이 조금 길어집니다. 다음은 귀하에게 유용할 수 있습니다.

awk -F'[, ]' '{if (NF!=0 && $1=="") {$1=prev} prev=$1}1' OFS=, inputfile

아이디어는 필드 ,와 공백을 분할하는 것입니다(후자는 입력의 첫 번째 줄을 처리하는 것입니다). 첫 번째 필드가 비어 있는지 확인그리고필드 수가 0이 아닌 경우(빈 줄을 처리하기 위해) 첫 번째 필드가 이전에 저장된 첫 번째 필드로 대체됩니다.

귀하의 입력에 대해 다음이 생성됩니다.

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
12:35:00,iscsi0,0,0.0,0,0,0.0,0.0
12:35:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:35:00,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
12:45:00,iscsi0,0,0.0,0,0,0.0,0.0
12:45:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:45:00,nfs1,0,0.0,0,0,0.0,0.0

답변2

그리고 sed:

sed '/^[0-9]/{               # if line starts with digit
h                            # overwrite hold buffer with pattern space content
s/\([^,]*\),.*/\1/           # extract timestamp
x                            # exchange: put the original line back into pattern
}                            # space and the timestamp in hold space
/^,/{                        # if line starts with a comma
G                            # append hold space (timestamp) to pattern space
s/\(.*\)\n\(.*\)/\2\1/       # swap the initial line content and the timestamp 
}' infile

한 줄:

sed -e'/^[0-9]/{h;s/\([^,]*\),.*/\1/;x' -e\} -e'/^,/{G;s/\(.*\)\n\(.*\)/\2\1/' -e\} infile

답변3

다른 sed:

sed '$!N;/\n,/s/\([^,]*\).*\n/&\1/;P;D' <in >out

!마지막 입력 라인이 아닌 각 입력 라인의 경우 $, ewline 문자 앞에 추가 입력 라인이 패턴 공간에 추가 sed됩니다 . 그런 다음 쉼표가 아닌 문자 의 첫 번째 세트를 ewline 뒤의 쉼표 바로 앞의 공백 에 복사하는 대체 작업을 시도합니다 . 그게 안된다면 나쁘지 않을 것 같아요.N\ns///^,\n

sed그런 다음 패턴 공간의 첫 번째 줄 P에 인쇄 하고 동일한 내용을 삭제한 다음 맨 위에서 시작하는 다음 입력 줄 쌍으로 루프를 다시 시작합니다.\nD

산출

12:33:41        unix,restarts
12:35:00,lofi4096,0,0.0,0,0,0.0,0.0
12:35:00,iscsi0,0,0.0,0,0,0.0,0.0
12:35:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:35:00,nfs1,0,0.0,0,0,0.0,0.0

12:45:00,lofi4096,0,0.0,0,0,0.0,0.0
12:45:00,iscsi0,0,0.0,0,0,0.0,0.0
12:45:00,scsi_vhc,0,0.0,0,0,0.0,0.0
12:45:00,nfs1,0,0.0,0,0,0.0,0.0

관련 정보