Extracción de parte de líneas con patrón específico usando awk, sed

18

Tengo una pregunta sobre los operadores awk / sed. Tengo un archivo grande que tiene el siguiente conjunto de líneas repetidas

Expression loweWallrhoPhi :  sum=-6.97168e-09
Expression leftWallrhoPhi :  sum=6.97168e-09
Expression lowerWallPhi :  sum=-5.12623e-12
Expression leftWallPhi :  sum=5.12623e-12
Expression loweWallrhoUSf :  sum=-6.936e-09
Expression leftWallrhoUSf :  sum=6.97169e-09
Expression lowerWallUSf :  sum=-5.1e-12
Expression leftWallUSf :  sum=5.12624e-12

Quiero extraer el valor después de la suma en cada caso en un archivo separado. ¿Es posible hacerlo de una vez?

Pimpalgaonkar Hrushikesh
fuente

Respuestas:

26

Con el comando grep:

grep -oP 'sum=\K.*' inpufile > outputfile

grep con -P(perl-regexp) admite parámetros \K, que se utilizan para ignorar los caracteres coincidentes previamente.

Con comando awk:

awk -F"=" '{print $NF}' inputfile > outputfile

Awk NFte da el número total de campos en un registro / línea. Entonces, el último valor de ese es el último número de campo en un registro / línea.

Con comando sed:

sed 's/^.*sum=//' inpufile > outputfile

^.*=sumreemplace todos los caracteres ( .*) entre el inicio de la línea ( ^) y los últimos caracteres ( sum=) con espacios en blanco char.

Resultado:

-6.97168e-09
6.97168e-09
-5.12623e-12
5.12623e-12
-6.936e-09
6.97169e-09
-5.1e-12
5.12624e-12

Si desea guardar cada valor en un archivo separado, use los comandos anteriores en un ciclo while:

while read line; do
    echo "$line" | grep -oP 'sum=\K.*'     > $(echo "$line" |awk '{print $2}');
   #echo "$line" | awk -F"=" '{print $NF}' > $(echo "$line" |awk '{print $2}');
   #echo "#line" | sed 's/^.*sum=//'       > $(echo "$line" |awk '{print $2}');
done < file
αғsнιη
fuente
Eso incluye el sum=y eso no es lo mismo que el valor despuéssum=
Anthon
OP quiere el valor después de la suma, también esa descripción awk de NF es horrible.
1
Para completar esta respuesta muy buena, también se puede utilizar cut: cut -d'=' -f2 file.
fedorqui
Esta es una muy buena respuesta. Me gustó. Gracias.
Jaffer Wilson
6

Si entiendo correctamente la pregunta, desea obtener solo valores después =y almacenar estos valores en archivos separados, según el segundo campo (?). Si tengo razón, intente algo como esto:

$ awk -F'[ =]' '{print $6>"file_"$2".txt"}' file

El resultado:

$ ls -1
  file_leftWallPhi.txt
  file_leftWallUSf.txt
  file_leftWallrhoPhi.txt
  file_leftWallrhoUSf.txt
  file_loweWallrhoPhi.txt
  file_loweWallrhoUSf.txt
  file_lowerWallPhi.txt
  file_lowerWallUSf.txt

$ cat  file_leftWallPhi.txt
  5.12623e-12
jimmij
fuente
@KasiyA No puedo reproducir su problema con GNU awk 4.0.2. El comando de mi respuesta también funciona con la -copción (modo de compatibilidad con UNIX tradicional awkdonde las extensiones GNU están deshabilitadas). Asegúrese de haber actualizado el archivo de entrada ya que se editó la pregunta original y se eliminaron las líneas vacías.
jimmij
1

Puedes hacerlo por sed

sed -E 's/^.* (\S+)\s*:.*=(\S+)/echo "\2" > "\1".txt/' file | bash

El guión descubre dos piezas en línea:

  1. entre espacios :yy debe contener algunos (más de 0) símbolos no espaciales;
  2. algunos (más de 0) símbolos no espaciales después =;

y formatear desde su comando en ejecución que se transfirió a través de la tubería a bash

Costas
fuente
Una respuesta mucho más versátil.
duanev