2012-08-15 7 views
5

que tienen la salida en este formato:¿Cuál es la forma óptima de extraer valores entre llaves en bash/awk?

Infosome - infotwo: (29333) - data-info-ids: (33389, 94934) 

que desea extraer los dos últimos números en el último par de llaves. Algunas veces solo hay un solo número en el último par de llaves.

Este es el código que utilicé.

echo "Infosome - infotwo: (29333) - data-info-ids: (33389, 94934)" | \ 
    tr "," " " | tr "(" " " | tr ")" " " | awk -F: '{print $4}' 

¿Es una forma más limpia de extraer los valores? o una forma más óptima?

+1

¿Qué quiere decir con limpio/óptimo? ¿Cuál es su criterio para el éxito? –

+0

Me refiero a una forma más profesional de extraer la información –

+3

Cambiar la palabra de "óptimo" a "profesional" no ayuda. :) –

Respuesta

13

Prueba esto:

awk -F '[()]' '{print $(NF-1)}' input | tr -d , 

Es una especie de refactorización de su comando.

+0

Eso es bastante increíble .. Me pregunto si OP quiere la coma todavía? – Levon

+0

no quiero una coma –

+0

@kev para que pueda especificar conjuntos de caracteres para el separador de campo en awk? No lo sabía, eso es bastante útil. – Levon

3
awk -F\('{gsub("[,)]", " ", $NF); print $NF}' input 

dará

33389 94934 

estoy un poco confuso sobre el significado de "óptima"/"profesional" en el contexto de este problema, pero esto sólo se utiliza un comando/herramienta, no estoy seguro si eso califica

O edificio en el enfoque de @ Kev (pero no necesitar tr para eliminar la coma):

awk -F'[(,)]' '{print $4, $5}' input 

salidas:

33389 94934 
+0

¡Es genial! +1 – kev

+0

Esto también es elegante. Y portátil (al menos, el primero)! :) +1 – ghoti

1

Esto también se puede hacer en bash puro. Suponiendo que el texto siempre se parece a la muestra en la pregunta, el siguiente debería funcionar:

$ text="Infosome - infotwo: (29333) - data-info-ids: (33389, 94934)" 
$ result="${text/*(}" 
$ echo ${result//[,)]} 
33389 94934 

Esto utiliza cáscara "expansión de parámetros" (que se puede buscar en la página del manual de bash) para despojar a la cadena de la misma forma en que lo hizo usando tr. Estrictamente hablando, las citas en la segunda línea no son necesarias, pero ayudan con el resaltado de sintaxis de StackOverflow. :-)

Usted puede alternativamente hacer esto un poco más flexible mediante la búsqueda de la campo real que le interesa Si está usando GNU awk, puede especificar RS con múltiples personajes:.

$ gawk -vRS=" - " -vFS=": *" ' 
    { f[$1]=$2; } 
    END { 
    print f["data-info-ids"]; 
    # Or you could strip the non-numeric characters to get just numbers. 
    #print gensub(/[^0-9 ]/,"","g",f["data-info-ids"]); 
    }' <<<"$text" 

Prefiero esta forma, porque realmente interpreta los datos de entrada por lo que son: texto estructurado que representa algún tipo de matriz.

Cuestiones relacionadas