이전 라인을 기반으로 라인 업데이트

이전 라인을 기반으로 라인 업데이트

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추가합니다 . 그런 다음 쉼표가 아닌 문자의 가능한 첫 번째 그룹을 줄 바꿈 바로 뒤의 쉼표 바로 앞의 공백에 복사하는 것과 관련된 대체를 시도합니다 . 그렇게 할 수 없다면, 뭐 해를 끼칠 일은 없을 것 같아요.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

관련 정보