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
-0
si es para registros delimitados por NUL. Úselo-0777
para sorber todo el archivo en la memoria (que no necesita aquí).Puede ser un poco fácil con
sed
primera parte
:1;N;$!b1
recolecta todas las líneas en el archivo dividido por\n
1 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
sed
guión difícil y recordar que el año comienza desde2
fuente
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;x
es definir la1;x
etiqueta 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 muchassed
implementaciones 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
-l
eliminará las nuevas líneas finales (y también agregará una a cadaprint
llamada, por eso lo usoprintf
en 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\n
al principio de la línea.printf
Imprime cada línea.Alternativamente, puede cambiar todos los
\n
caracteres a\0
, luego cambiar aquellos\0
que están justo antes de una cadena de números a\n
nuevamente:Para que coincida solo con cadenas de 8 números, use esto en su lugar:
fuente
printf
es el formato . Usoprintf "%s", $_
%10000000000s
por ejemplo.perl
,echo %.10000000000f | perl -ne printf
pone 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 puedemksh
hacer 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; print
que funcionará
fuente