2012-02-13 12 views
10

he tratado de extraer un número que figura a continuación, pero no se imprime nada en la pantalla:sed grupo de extracción de dígitos

echo "This is an example: 65 apples" | sed -n 's/.*\([0-9]*\) apples/\1/p' 

Sin embargo, recibo el mensaje '65', si ambas cifras se comparan por separado, como se indica a continuación:

echo "This is an example: 65 apples" | sed -n 's/.*\([0-9][0-9]\) apples/\1/p' 
65 

¿Cómo se puede hacer coincidir un número tal que no sé el número de dígitos de un número a extraer por ejemplo, puede ser 2344 en lugar de 65?

Respuesta

14
$ echo "This is an example: 65 apples" | sed -r 's/^[^0-9]*([0-9]+).*/\1/' 
65 
+2

+1, pero ten en cuenta que no todos -r apoyo sed y por lo tanto no puede utilizar los botones '+ 'modificador y debe escapar de los parens. –

+1

¿Por qué una expresión regular como '[([0-9] *) apple]' (http://sprunge.us/feGV) no funciona en sed? Funciona bien en Python. –

+0

así que ...^[^ 0-9] * corresponden a todo lo que no sea un dígito al comienzo de la línea. [0-9] + por lo menos un dígito o más, ¿verdad? – baltoro

1

Lo que está viendo es el comportamiento codicioso de regex. En su primer ejemplo, .* engulle todos los dígitos. Algo como esto lo hace:

echo "This is an example: 65144 apples" | sed -n 's/[^0-9]*\([0-9]\+\) apples/\1/p' 
65144 

De esta manera, no se puede coincidir con cualquier dígito en el primer bit. Algunos dialectos de expresiones regulares tienen una forma de pedir coincidencias no codiciosas, pero no creo que sed tenga una.

3

Se debe a que su primera .* es codiciosos, y su [0-9]* permite a 0 o más dígitos. Por lo tanto, el .* engulle tanto como puede (incluidos los dígitos) y el [0-9]* no coincide con nada.

que puede hacer:

echo "This is an example: 65 apples" | sed -n 's/.*\b\([0-9]\+\) apples/\1/p' 

donde me obligó a los [0-9] para que coincida con al menos un dígito, y tambien tiene añadido un límite de palabra antes de los dígitos por lo que se corresponde con el número entero.

Sin embargo, es más fácil de usar grep, en el que coinciden sólo el número:

echo "This is an example: 65 apples" | grep -P -o '[0-9]+(?= +apples)' 

El -P significa "expresiones regulares de Perl" (así que no tiene que preocuparse de escapar de la '+').

El -o significa "solo imprimir las coincidencias".

El (?= +apples) significa que coincide con los dígitos seguidos de la palabra manzanas.

+0

Creo que sed no identifica el identificador '?' No codicioso. [Ver esto] (http://stackoverflow.com/a/1103177/167814). –

+0

ahh, ya veo. aclamaciones. –

+0

el primer ejemplo no funciona –

0
echo "This is an example: 65 apples" | ssed -nR -e 's/.*?\b([0-9]*) apples/\1/p' 

Sin embargo, necesitará súper sed para que esto funcione. El -R permite perl regexp.

1

Una forma sencilla para la extracción de todos los números de una cadena

echo "1213 test 456 test 789" | grep -P -o "\d+" 

Y el resultado:

1213 
456 
789