Estoy tratando de encontrar aquí alguna pregunta anterior que pueda usar pero desafortunadamente no puedo encontrar mi caso exacto.
Me gustaría obtener el resultado de otro comando que se vea así:
pattern.d
17.91
17.55
pattern.b
pattern.a
7.21
9.34
pattern.c
a esto:
pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000
Intento explicar un poco más: después de cada línea que contiene la cadena "patrón" siempre debe haber un número. Si no, me gustaría insertar una nueva línea con el valor 1000.
Tenga en cuenta que el patrón tiene una "extensión" (.a .b .c .d pero no números en la "extensión") que varía y me ayudará a ordenar alfabéticamente el contenido más adelante.
EDITAR: He aceptado una respuesta, pero en caso de que alguien quiera buscar otra variación, debo especificar que la aparición del "patrón" varía y podría haber más de 2 o 3 consecutivos, como en:
pattern.a
pattern.d
pattern.c
pattern.d
pattern.b
17.91
Respuesta1
Aquí hay una sed
solución que funcionará con cualquier entrada (por ejemplo, varias líneas consecutivas coincidentes pattern
):
sed '1{ # when on first line
x # exchange
s/^/1000/ # replace the empty hold buffer with "1000"
x # exchange back
}
: do # label "do"
/pattern/{ # if the current line matches "pattern"
${ # if we're on the last line
G # append hold buffer content to pattern space
b # go to end of script
}
n # otherwise print and pull in the next line
/^[[:digit:]]/!{ # if this one doesn't start with a digit
x # exchange
p # print (the pattern space is now "1000")
x # exchange back
b do # go to label "do"
}
}' infile
Con gnu sed
ello se puede escribir como
sed '1{x;s/^/1000/;x};:b;/pattern/{${G;b};n;/^[[:digit:]]/!{x;p;x;bb}}' infile
Puedes hacer algo similar con awk
:
awk -vc=0 '!/^[[:digit:]]/{
if (c) {print "1000"}
}
{ if (/pattern/){c=1} else{c=0}
}
END{if (c){print "1000"}
};1' infile
es decir, configurar c=1
en las líneas que coinciden pattern
y c=0
en el resto de las líneas y en cada línea que no comienza con un dígito (así como en el END
bloque) verifique si c
está configurado (o 1
, es decir, la línea anterior coincide pattern
), si es así imprimir 1000
.
Respuesta2
sed -e '
$!{
/pattern\.[a-z]/N
/\n/!b
/\n[+-]\{0,1\}[.][0-9]\{1,\}$/b
/\n[+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}$/b
h;s/\(.*\n\).*/\11000/p
g;D
}
/pattern\.[a-z]/a\
1000
' yourfile
Resultados
pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000
Laboral
- Mientras no sea en eof,
$!{...}
agregamos la siguiente línea al espacio del patrón con la condición de que la línea actual sea una línea de interés. - Luego omitimos cualquier procesamiento adicional en los casos de: a) No se encontró ninguna nueva línea => no hay patrón en la línea actual. b) Un número de coma flotante con el formato .nnn en la segunda línea. c) En la segunda línea se encuentra exclusivamente un número en coma flotante con el formato mmm, mmm. o mmm.nnn. d) Salvo cualquiera de las posibilidades => necesitamos agregar el número mágico 1000 al final de la siguiente línea después de la nueva línea.
Respuesta3
Si nunca hay más de dos instancias consecutivas de pattern
y tienes GNU sed, entonces:
sed '/^pattern/ {$!N; /\n[0-9]/b; s/$/\n1000/M}' file
pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000
Cómo funciona:
- si la línea actual comienza con
pattern
entonces- siempre que no estemos en EOF, agregue la siguiente línea
- si hay un dígito después de la nueva línea (esto podría hacerse más específico), entonces
b
salga (es decir, continúe con la siguiente línea); demás - sustituya la primera línea que termina con una nueva línea y
1000
M
El modificador específico de GNU permite $
hacer coincidir \n
o $
para que maneje tanto el caso "normal" como el caso EOF donde no se agrega ninguna línea siguiente.
Respuesta4
awksolución:
awk '{ if ($0 ~ /pattern/) { # if it's a `pattern` line
if ((getline nl) > 0) { # check if next record exists
# if next record hasn't number - insert `1000`, otherwise - print current and next records as they are
print ((nl !~ /^[0-9]/)? $0 ORS 1000 ORS nl: $0 ORS nl)
} else {
print $0 ORS 1000 # if the file ends up with pattern - insert `1000`
}
} else {
print $0 # print other record
}
}' file
La salida:
pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000