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
\n
s///
^,
\n
sed
그런 다음 패턴 공간의 첫 번째 줄 P
에 인쇄 하고 동일한 내용을 삭제한 다음 맨 위에서 시작하는 다음 입력 줄 쌍으로 루프를 다시 시작합니다.\n
D
산출
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