Entonces tengo una línea:
ID: 54376
¿Me pueden ayudar a hacer una expresión regular que solo devolvería números sin "ID:"?
NOTA: esta cadena está en un archivo.
Entonces tengo una línea:
ID: 54376
¿Me pueden ayudar a hacer una expresión regular que solo devolvería números sin "ID:"?
NOTA: esta cadena está en un archivo.
Respuestas:
Prueba esto:
grep -oP '(?<=ID: )[0-9]+' file
o:
perl -nle 'print $1 if /ID:.*?(\d+)/' file
-o
y -P
son extensiones de GNU para grep
. -o
funciona también en los BSD. El soporte PCRE con -P
no siempre se compila tampoco.
Use egrep
con -o
o grep
con la -Eo
opción para obtener solo el segmento coincidente. Use [0-9]
como expresión regular para obtener solo números:
grep -Eo [0-9]+ filename
Hay muchas formas de hacer esto. Por ejemplo:
Use GNU grep
con PCRE recientes y haga coincidir los números después de ID:
:
grep -oP 'ID:\s*\K\d+' file
Use awk
e imprima el último campo de todas las líneas que comienzan conID:
awk '/^ID:/{print $NF}' file
Sin embargo, eso también imprimirá campos que no son números, para obtener solo números, y solo en el segundo campo, use
awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
Use GNU grep con Expresiones regulares extendidas y analícelo dos veces:
grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
\K
está haciendo en el primer ejemplo?
-o
para imprimir solo la parte coincidente pero también descartar cosas que no me interesan. Comparar echo "foobar" | grep -oP "foobar"
yecho "foobar" | grep -oP 'foo\Kbar'
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'
Eso imprimirá solo todos los números y espacios que ocurran después ID: 54376
en cualquier entrada de archivo.
Acabo de actualizar un poco lo anterior para hacerlo un poco más rápido *
y no p
eliminar líneas en blanco después de eliminar los caracteres que no son {numéricos, espacio}.
Aborda las líneas desde la expresión regular /ID: 54376/
,
hasta la $
última y en ellas s///
elimina todos los *
caracteres o ^
no, [^ 0-9]*
luego no p
borra /
ninguna /
línea con un .
carácter restante.
{
echo line
printf 'ID: 54376\nno_nums_or_spaces\n'
printf '%s @nd 0th3r char@cter$ %s\n' $(seq 10)
echo 'ID: 54376'
} | sed -n '/ID 54376/,${s/[^ 0-9]*//g;/./p}'
54376
1 03 2
3 03 4
5 03 6
7 03 8
9 03 10
54376
Usando sed:
{
echo "ID: 1"
echo "Line doesn't start with ID: "
echo "ID: Non-numbers"
echo "ID: 4"
} | sed -n '/^ID: [0-9][0-9]*$/s/ID: //p'
El -n
es "no imprime nada por defecto", /^ID: [0-9][0-9]*$/
es "para líneas que coinciden con esta expresión regular" (comienza con "ID:", luego 1 o más dígitos, luego final de línea), y el s/ID: //p
es de la forma s/pattern/repl/flags
- s
significa que estás haciendo un sustituto, para reemplazar el patrón "ID: "
con texto de reemplazo ""
(cadena vacía) usando la p
bandera, que significa "imprimir esta línea después de hacer la sustitución".
Salida:
1
4
Otro comando de GNU sed,
sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file
Imprime cualquier número después ID:
+
. Si la diferencia entre un personaje y 3 caracteres es la secuencia de comandos no funcionen en todas sed
s probablemente debería hacer: sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'
. Su respuesta también pierde el primero ID: [0-9]
en una línea que contiene dos ocurrencias de ID: [0-9]
.
Use grep + awk:
grep "^ID" your_file | awk {'print $2'}
Bono: fácil de leer :)
grep
si lo estás usando awk
. awk '/^ID/ { print $2 }'
hace lo mismo y evita los problemas de almacenamiento en línea de grep . También es más o menos lo mismo que una de las soluciones en la respuesta de @terdon.