Extraindo parte de linhas com padrão específico usando awk, sed

18

Eu tenho uma pergunta sobre os operadores awk / sed. Eu tenho um arquivo grande que tem o seguinte conjunto de linhas 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

Eu quero extrair valor após soma em cada caso em arquivo separado. É possível fazê-lo de uma só vez?

    
por Pimpalgaonkar Hrushikesh 11.11.2014 / 11:13

3 respostas

26

Com o comando grep:

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

O parâmetro grep com -P (perl-regexp) suporta \K , que é usado para ignorar os caracteres previamente correspondidos.

Com o comando awk:

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

O awk NF fornece o número total de campos em um registro / linha. Então, o último valor é o último número de campo em um registro / linha.

Com o comando sed:

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

^.*=sum substitui todos os caracteres ( .* ) entre o início da linha ( ^ ) e os últimos caracteres ( sum= ) com o espaço em branco 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

Se você quiser salvar cada valor em um arquivo separado, use os comandos acima em um loop 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
    
por 11.11.2014 / 11:19
6

Se eu entender corretamente a pergunta que você deseja obter somente valores após = e armazenar esses valores em arquivos separados, com base no segundo campo (?). Se eu tiver razão, tente algo assim:

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

O 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
    
por 11.11.2014 / 11:21
1

Você pode fazer isso por sed

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

O script descobre duas peças na linha:

  1. entre espaços e : e deve conter alguns (mais de 0) símbolos não espaciais;
  2. alguns (mais de 0) símbolos não espaciais após = ;

e formata a partir do seu comando de execução, que é transferido através do pipe para bash

    
por 11.11.2014 / 12:17