Me considero bastante bueno con las expresiones regulares, pero esta parece ser sorprendentemente complicada.
Quiero recortar todos los espacios en blanco, excepto los que están entre los caracteres "" y [].
Usé esta expresión regular ("[^"]*"|\S+)\s+ pero dividí la parte [06/Jan/2021:17:50:09 +0300] de mi registro en dos bloques.
Aquí está mi línea de registro completa:
[06/Jan/2021:17:50:09 +0300] "" 10.139.3.194 407 "CONNECT clients5.google.com:443 HTTP/1.1" "" "-" "" 4245 75 "" "" "81" ""El resultado que obtengo se basa en mi expresión regular usando el comando sed (reemplazando los espacios en blanco por una coma):
[06/Jan/2021:17:50:09,+0300],"",10.139.3.194,407,"CONNECT clients5.google.com:443 HTTP/1.1","","-","",4245,75,"","","81",""Finalmente el resultado que quiero tener:
[06/Jan/2021:17:50:09 +0300],"",10.139.3.194,407,"CONNECT clients5.google.com:443 HTTP/1.1","","-","",4245,75,"","","81",""Dado que la entrada de estas muestras se parece a los registros, teniendo en cuenta que siempre estarán en el mismo formato; con esto podría intentar seguir el código awk , escrito y probado en los ejemplos mostrados en GNU awk .
awk -v FPAT='[^]]*\\]|"[^"]*"|([0-9]+\\.){3}[0-9]+|[0-9]{2,4}' -v OFS="," '{$1=$1} 1' Input_fileExplicación:
awk aquí. Que tiene la opción FPAT disponible en él.OFS (separador de campo de salida) como , también para todas las líneas.awk (restableciendo el primer campo) para aplicarle el valor OFS según el requisito de OP. Lo que asegurará que las comas aparezcan en la salida solo según sea necesario.Explicación de expresiones regulares:
[^]]*\\] ##Matching everything till ] followed by ] here. | ##OR "[^"]*" ##Matching from " till first occurrence of " everything between them including " | ##OR ([0-9]+\\.){3}[0-9]+ ##Matching digits followed by dot 3 times followed by digits | ##OR [0-9]{2,4} ##Matching 2 to 4 digits here.Puede unir cadenas entre corchetes agregando \[[^][]*] como alternativa al patrón del Grupo 1:
sed -E 's/(\[[^][]*]|"[^"]*"|\S+)\s+/\1,/g' Ahora, el patrón POSIX ERE (sintaxis habilitada con la opción -E ) coincide
(\[[^][]*]|"[^"]*"|\S+) - Grupo 1: ya sea\[[^][]*] - un [ carácter, luego cero o más caracteres que no sean [ y ] y luego un ] carácter|"[^"]*" - un " carácter, cero o más caracteres que no sean " y luego un " carácter| - o\S+ - uno o más caracteres que no sean espacios en blanco\s+ - uno o más espacios en blancoVea la demostración en línea :
#!/bin/bash s='[06/Jan/2021:17:50:09 +0300] "" 10.139.3.194 407 "CONNECT clients5.google.com:443 HTTP/1.1" "" "-" "" 4245 75 "" "" "81" ""' sed -E 's/(\[[^][]*]|"[^"]*"|\S+)\s+/\1,/g' <<< "$s"Producción:
[06/Jan/2021:17:50:09 +0300],"",10.139.3.194,407,"CONNECT clients5.google.com:443 HTTP/1.1","","-","",4245,75,"","","81",""