mi archivo de texto se ve así:
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341
ahora quiero eliminar Liquid penetration 95% mass (m)
de mis líneas para obtener solo los valores. ¿Cómo debería hacerlo?
grep -o '[^[:space:]]\+$' file
\S+$
con-E
o con-P
.) Por lo tanto, este tipo de solución no es inherentemente lenta. Pero todavía no puedo acercarme alcut
método de αғsнιη , que también ganó su punto de referencia .Respuestas:
Si solo hay un
=
signo, puede eliminar todo antes e incluirlo=
así:Si desea cambiar el archivo original, use la
-i
opción después de probar:Notas
-r
use ERE para que no tengamos que escapar(
y)
s/old/new
reemplazarold
connew
.*
cualquier número de caracteres(things)
salvarthings
a elementos detectados después con\1
,\2
, etc.fuente
s/^.*= //
funcionaría igualmente bien, ya que el valor correcto está al final de la línea.\1
etc. tiene algún valor para las personas que tierra sobre esta cuestión en la búsqueda, que no tienen un problema tan simpleEste es un trabajo para
awk
; suponiendo que los valores ocurran solo en el último campo (según su ejemplo):NF
es unaawk
variable, se expande al número de campos en un registro (línea), por lo tanto$NF
(tenga$
en cuenta el frente) contiene el valor del último campo.Ejemplo:
fuente
Decidí comparar las diferentes soluciones, enumeradas aquí. Para este propósito, he creado un archivo grande, basado en el contenido proporcionado por el OP:
Creé un archivo simple, llamado
input.file
:Luego ejecuté este bucle:
La ventana del terminal estaba bloqueada. Ejecuté
killall tee
desde otra terminal. Luego examiné el contenido del archivo mediante los comandos:less input.file
ycat input.file
. Se veía bien, excepto la última línea. Así que eliminé la última línea y creé una copia de seguridad:cp input.file{,.copy}
(debido a los comandos que usan la opción in situ ).El recuento final de las líneas en el archivo
input.file
es 2 192 473 . Obtuve ese número por el comandowc
:Aquí está el resultado de la comparación:
grep -o '[^[:space:]]\+$'
sed -ri 's/.* = (.*)/\1/'
Alternativamente, si redirigimos la salida a un nuevo archivo, el comando es más rápido:
gawk '{gsub(".*= ", "");print}'
rev | cut -d' ' -f1 | rev
grep -oP '.*= \K.*'
sed 's/.*= //'
(respectivamente, la-i
opción hace que el comando sea un poco más lento)perl -pe 's/.*= //'
(La-i
opción no produce una gran diferencia en la productividad aquí)awk '{print $NF}'
cut -c 35-
cut -d= -f2
La fuente de la idea.
fuente
cut -d= -f2
solución gana. jajawc -l
salida a tres números? Cuando no se pasan otras opciones, la-l
opción debe suprimir todo menos el recuento de líneas.wc
Realmente había mostrado esos espacios? ¿Hay configuraciones regionales para las que hará eso?) ¡Gracias por la actualización!wc
una vez más. No sé dónde estaba mi ingenio hoy temprano, pero realmente no podía entenderlos. De hecho, los espacios eran separadores de grupos de dígitos , ywc
no los agrega :)Con
grep
y el-P
por tenerPCRE
(Interpretar el patrón como un P erl- C ompatible R egular E Xpression) y el-o
patrón para imprimir emparejado solo. La\K
notificación ignorará la parte coincidente anterior a sí misma.O podría usar el
cut
comando en su lugar.fuente
cut
método en esta respuesta también fue el claro ganador en un benchmark más pequeño que ejecuté que probó menos métodos pero usó un archivo de entrada más grande. Fue bastante más de diez veces más rápido que la variante rápida del método que personalmente me gusta (y que mi respuesta es principalmente sobre).Como el prefijo de línea siempre tiene la misma longitud (34 caracteres), puede usar
cut
:fuente
Invierta el contenido del archivo con
rev
, canalice la salidacut
con espacio como delimitador y 1 como campo de destino, luego inviértalo nuevamente para obtener el número original:fuente
Esto es simple, breve y fácil de escribir, comprender y verificar, y personalmente me gusta:
grep
en Ubuntu , cuando se invoca con-E
o-P
, toma la abreviatura\s
para significar un carácter de espacio en blanco (en la práctica, generalmente un espacio o tabulación) y\S
significa cualquier cosa que no sea uno. Usando el cuantificador+
y el ancla de fin de línea$
, el patrón\S+$
coincide con uno o más espacios en blanco al final de una línea . Puedes usar en-P
lugar de-E
; el significado en este caso es el mismo pero se usa un motor de expresiones regulares diferente , por lo que pueden tener características de rendimiento diferentes .Esto es equivalente a la solución comentada de Avinash Raj (solo con una sintaxis más fácil y compacta):
Estos enfoques no funcionan si no puede haber espacios en blanco después del número. Pueden modificarse para que lo hagan, pero no veo ningún punto en entrar en eso aquí. Aunque a veces es instructivo generalizar una solución para trabajar en más casos, no es práctico hacerlo con tanta frecuencia como la gente tiende a suponer, porque generalmente no hay forma de saber en cuál de las muchas formas incompatibles diferentes el problema podría necesitar. ser generalizado
El rendimiento es a veces una consideración importante. Esta pregunta no estipula que la entrada es muy grande, y es probable que cada método que se haya publicado aquí sea lo suficientemente rápido. Sin embargo, en caso de que se desee velocidad, aquí hay un pequeño punto de referencia en un archivo de entrada de diez millones de líneas:
Lo ejecuté dos veces en caso de que el pedido importara (como a veces lo hace para tareas pesadas de E / S) y porque no tenía una máquina disponible que no estuviera haciendo otras cosas en segundo plano que pudieran sesgar los resultados. De esos resultados concluyo lo siguiente, al menos provisionalmente y para archivos de entrada del tamaño que utilicé:
¡Guauu! Pasar
-P
(para usar PCRE ) en lugar de-G
(el valor predeterminado cuando no se especifica un dialecto) o se-E
hacegrep
más rápido en un orden de magnitud. Entonces, para archivos grandes, puede ser mejor usar este comando que el que se muestra arriba:¡¡GUAU!! El
cut
método de la respuesta de αғsнιη , es más de un orden de magnitud más rápido que incluso la versión más rápida de mi camino! También fue el ganador en el punto de referencia de pa4080 , que cubrió más métodos que este pero con una entrada menor, y es por eso que lo elegí, de todos los otros métodos, para incluir en mi prueba. Si el rendimiento es importante o los archivos son enormes, creo que debería usarse el método de αғsнιη .cut -d= -f2 file
cut
Esto también sirve como un recordatorio de que lo simple
cut
y laspaste
utilidades no deberían olvidarse , y tal vez deberían preferirse cuando corresponda, a pesar degrep
que a menudo se ofrecen herramientas más sofisticadas como soluciones de primera línea (y que yo personalmente estoy más acostumbrado) a usar).fuente
perl
- s sustituya el patrón/.*= /
con una cadena vacía//
:De
perl --help
:sed
- sustituir el patrón con una cadena vacía:o (pero más lento que el anterior) :
gawk
- sustituir el patrón".*= "
con una cadena vacía""
:De
man gawk
:fuente