
Estou com um problema porque não estou familiarizado com o awk. Eu tenho um arquivo csv gerado a partir da saída sar -d convertida para o estilo 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
e eu quero converter para isso
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
Minha tentativa, mas como o awk lê linha por linha, não sei como manter o valor da linha anterior. Eu esperaria que o que tenho funcionasse. Alguma ideia de como posso obter o resultado desejado. Eu tentei com o awk, mas acho que isso deveria ser possível com sed ou da maneira mais difícil com um script de shell personalizado (estou tentando evitar fazer esta parte).
#!/usr/bin/awk -f
BEGIN {
FS=",";
}
{
print $1
if ($1 != "") {
mydate=$1;
print $0;
}
else {
print $mydate","$0;
}
}
Executando o sistema com Solaris 11.1.
Responder1
Fica um pouco longo porque parece que há linhas em branco na entrada. O seguinte pode funcionar para você:
awk -F'[, ]' '{if (NF!=0 && $1=="") {$1=prev} prev=$1}1' OFS=, inputfile
A ideia é dividir os campos em ,
espaços em branco (este último para lidar com a primeira linha de entrada). Verifique se o primeiro campo está em brancoeo número de campos não for zero (lidar com linhas em branco) e, em seguida, substituir o primeiro campo pelo primeiro campo armazenado anteriormente.
Para sua opinião, produziria:
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
Responder2
Com 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
em uma linha:
sed -e'/^[0-9]/{h;s/\([^,]*\),.*/\1/;x' -e\} -e'/^,/{G;s/\(.*\)\n\(.*\)/\2\1/' -e\} infile
Responder3
Outro sed
:
sed '$!N;/\n,/s/\([^,]*\).*\n/&\1/;P;D' <in >out
Para cada linha de entrada que !
não seja a $
última, sed
anexará a N
linha de entrada ext ao espaço padrão precedido por um \n
caractere ewline. Em seguida, ele tentará uma s///
substituição que envolve copiar o primeiro grupo possível de ^,
caracteres sem vírgula para o espaço imediatamente anterior a uma vírgula que segue imediatamente um \n
ewline. Se não puder fazer isso, bem, nenhum dano causado, eu acho.
sed
irá então P
imprimir até a primeira \n
linha ew no espaço padrão e D
eletá-la antes de iniciar o ciclo novamente a partir do topo com o próximo par de linhas de entrada.
SAÍDA
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