Tengo un archivo de registro que debe analizarse y analizarse. El archivo contiene algo similar como a continuación:
Expediente:
20141101 server contain dump
20141101 server contain nothing
{uekdmsam ikdas
jwdjamc ksadkek} ssfjddkc * kdlsdl
sddsfd jfkdfk
20141101 server contain dump
Según el escenario anterior, tengo que verificar si la línea de inicio no contiene la fecha o el número que debo agregar a la línea anterior.
Archivo de salida:
20141101 server contain dump
20141101 server contain nothing {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdl sddsfd jfkdfk
20141101 server contain dump
text-processing
sed
awk
William R
fuente
fuente

-0si es para registros delimitados por NUL. Úselo-0777para sorber todo el archivo en la memoria (que no necesita aquí).Puede ser un poco fácil con
sedprimera parte
:1;N;$!b1recolecta todas las líneas en el archivo dividido por\n1 línea largasímbolo de nueva línea de la tira de la segunda parte si seguía un símbolo sin dígitos con posibles espacios entre ellos.
Para evitar la limitación de memoria (especialmente para archivos grandes) puede usar:
O olvidar un
sedguión difícil y recordar que el año comienza desde2fuente
tr '\n' $'\a' | sed $'s/\a\a*\( *[^0-9]\)/\1/g' | tr $'\a' '\n'yo mismo.+es\{1,\}.[\n]tampoco es portátil.\n\{1,\}Sería POSIX.: 1;xes definir la1;xetiqueta en seds POSIX. Por lo que necesita:sed -e :1 -e 'N;$!b1' -e 's/\n\{1,\}\( *[^0-9]\)/\1/g'. También tenga en cuenta que muchassedimplementaciones tienen un pequeño límite en el tamaño de su espacio de patrones (POSIX solo garantiza 10 x LINE_MAX IIRC).Una forma sería:
Sin embargo, eso también elimina la nueva línea final. Para agregarlo nuevamente, use:
Explicación
El
-leliminará las nuevas líneas finales (y también agregará una a cadaprintllamada, por eso lo usoprintfen su lugar. Luego, si la línea actual comienza con números (/^\d+/) y el número de línea actual es mayor que uno ($.>1, esto es necesario para evitar agregar un extra línea vacía al principio), agregue una\nal principio de la línea.printfImprime cada línea.Alternativamente, puede cambiar todos los
\ncaracteres a\0, luego cambiar aquellos\0que están justo antes de una cadena de números a\nnuevamente:Para que coincida solo con cadenas de 8 números, use esto en su lugar:
fuente
printfes el formato . Usoprintf "%s", $_%10000000000spor ejemplo.perl,echo %.10000000000f | perl -ne printfpone mi máquina de rodillas.Intenta hacer esto usando awk :
Para usarlo:
fuente
Otra forma más simple (que mi otra respuesta) usando el algoritmo de awk y terdon :
fuente
END{print ""}. Alternativa:awk -v ORS= 'NR>1 && /^[0-9]{8}/{print "\n"};1;END{print "\n"}'fuente
El programa en bash:
en forma de una línea:
Solución con barras invertidas conservando (
read -r) y espacios iniciales (justoIFS=despuéswhile):formulario de una línea:
fuente
n. También elimina espacios en blanco. Pero puedemkshhacer esto:while IFS= read -r L; do [[ $L = [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]* ]] && print; print -nr -- "$L"; done; printque funcionará
fuente