
Tengo un problema porque no estoy familiarizado con awk. Tengo un archivo csv generado a partir de la salida sar -d convertido al 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
y quiero convertir a esto
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
Mi intento, pero como awk lee línea por línea, no sé cómo mantener el valor de la línea anterior. Esperaría que lo que tengo funcione. ¿Alguna idea de cómo puedo obtener el resultado deseado? Lo intenté con awk, pero supongo que esto debería ser posible con sed o de la manera más difícil con un script de shell personalizado (estoy tratando de evitar hacer esta parte).
#!/usr/bin/awk -f
BEGIN {
FS=",";
}
{
print $1
if ($1 != "") {
mydate=$1;
print $0;
}
else {
print $mydate","$0;
}
}
Ejecutando el sistema con Solaris 11.1.
Respuesta1
Se vuelve un poco largo porque parece que tienes líneas en blanco en la entrada. Lo siguiente podría funcionar para usted:
awk -F'[, ]' '{if (NF!=0 && $1=="") {$1=prev} prev=$1}1' OFS=, inputfile
La idea es dividir los campos en ,
espacios en blanco (este último para manejar la primera línea de entrada). Compruebe si el primer campo está en blancoyel número de campos no es cero (maneja líneas en blanco), luego reemplaza el primer campo con el primer campo previamente almacenado.
Para su aporte, produciría:
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
Respuesta2
Con 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
en una línea:
sed -e'/^[0-9]/{h;s/\([^,]*\),.*/\1/;x' -e\} -e'/^,/{G;s/\(.*\)\n\(.*\)/\2\1/' -e\} infile
Respuesta3
Otro sed
:
sed '$!N;/\n,/s/\([^,]*\).*\n/&\1/;P;D' <in >out
Para cada línea de entrada que !
no sea la $
última, sed
se agregará la N
línea de entrada externa al espacio del patrón precedida por un \n
carácter de línea nueva. Luego intentará una s///
sustitución que implica copiar el primer grupo posible de ^,
caracteres que no sean comas en el espacio que precede a una coma que sigue inmediatamente a una \n
línea ew. Si no puede hacerlo, supongo que no habrá ningún daño.
sed
Luego P
imprimirá hasta la primera \n
línea ew en el espacio del patrón y D
la eliminará antes de comenzar el ciclo nuevamente desde la parte superior con el siguiente par de líneas de entrada.
PRODUCCIÓN
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