Tengo un archivo que contiene, por ejemplo:
Diameter is defined by... diameter 26.5/9 diameter has been changed diameter has changed and then DIAMETER 942/10 yada di yada DiameterEn salida quiero:
26.5/9 942/10Hasta donde yo entiendo:
Necesito buscar una cadena "diámetro" que no distinga entre mayúsculas y minúsculas seguida de un espacio y un carácter numérico que volver a "diámetro" e imprimir la siguiente cadena entre espacios.
Solo he logrado llegar a algo como esto:
sed -n '/^.*diameter\s\+\(\w\+\).*$/s//\1/p'pero solo imprime una sola palabra (separada por caracteres no alfanuméricos) después de una primera aparición de la palabra "diámetro" que distingue entre mayúsculas y minúsculas. La salida se vería así:
26 hasPrimera solución: usar la función de match de awk escrita y probada en GNU awk . Usando la opción IGNORECASE de GNU awk para que pueda coincidir tanto con el diameter como con el DIAMETER en expresiones regulares. Usando la función de match de awk para hacer coincidir el diameter [0-9]+(\.[0-9]+)?\/[0-9]+ que coincidirá con el diámetro seguido del espacio seguido de los dígitos seguidos del punto opcional y dígitos seguidos de dígitos para obtener valores de diámetro.
awk -v IGNORECASE="1" ' match($0,/diameter [0-9]+(\.[0-9]+)?\/[0-9]+/){ print substr($0,RSTART+9,RLENGTH-9) } ' Input_file Segunda solución: con las muestras mostradas, intente seguir el código awk . Usando la capacidad RS de awk aquí, mencionando expresiones regulares (lo mismo explicado en la primera solución anterior) y en el programa principal en el valor RT dividiéndolo en matriz arr e imprimiendo la segunda parte de arr, que es el valor del diámetro.
awk -v RS='(diameter|DIAMETER) [0-9]+(\\.[0-9]+)?\\/[0-9]+' ' RT{ split(RT,arr) print arr[2] } ' Input_file 3ra solución: usar sed escrito y probado en GNU sed . Usando la opción -E de sed para habilitar ERE (expresiones regulares extendidas) aquí. Luego, en el programa principal, haga coincidir todo hasta el diameter O DIAMETER desde el inicio del valor, seguido de espacios seguidos de la misma expresión regular mencionada anteriormente en un grupo de captura (una característica en sed para guardar valores en el búfer temporal para usar más adelante) y sustituyendo el valor de toda la línea solo con la parte capturada.
sed -E 's/.*(diameter|DIAMETER)\s+([0-9]+(\.[0-9]+)?\/[0-9]+).*/\2/' Input_file Cuarta solución: con GNU grep usando expresiones regulares, intente seguir. Uso de las opciones -o y -P de grep para imprimir solo la parte coincidente y habilitar la expresión regular de PCRE, respectivamente. En el programa principal, haga una coincidencia diferida desde el inicio del valor hasta la cadena de diameter O DIAMETER seguida de espacios, luego use la opción \K para OLVIDAR todos los valores matemáticos hasta aquí. A lo que sigue una expresión regular que imprimirá el valor requerido por OP.
grep -oP '.*?(?:diameter|DIAMETER)\s+\K[0-9]+(\.[0-9]+)?\/[0-9]+' Input_fileLa salida será la siguiente:
26.5/9 942/10También puedes usar grep:
$ grep -Pio '(?<=diameter\s)[\d.\/]+(?=\s)' input_file 26.5/9 942/10(?<=) : Mirada positiva hacia atrás.diameter\s : Coincide con el diameter .[\d.\/] : Coincide con un dígito, un punto o una barra.+ : Coincide con el token anterior entre una vez y un número ilimitado de veces (codicioso).(?=) : Anticipación positiva.\s : Coincide con un espacio en blanco.-P : expresión regular de estilo Perl.-i : No distingue entre mayúsculas y minúsculas.-o : Imprime solo la parte coincidente.Con GNU sed for i para que la coincidencia no distinga entre mayúsculas y minúsculas:
$ sed -n 's/.*diameter \([0-9][^ ]*\).*/\1/pI' file 26.5/9 942/10Con cualquier sed+tr:
tr 'AZ' 'az' file | sed -n 's/.*diameter \([0-9][^ ]*\).*/\1/p'