Grep resto da linha ... depois da partida


8

Eu tenho um arquivo contendo apenas duas linhas, com a seguinte estrutura:

$ cat /tmp/pwpower.log
000D6F0000D34227, -114.10
000D6F0001A405C4, -130.09

Os valores são valores de energia da minha usina solar. Valor negativo significa geração.

Eu precisaria dos valores extraídos via grep / sed / awk - qualquer que seja a maneira mais inteligente. Eu preciso ter os dois valores extraídos separadamente e sem o sinal de menos.

O que faço agora é meio estúpido, mas funciona - tenho certeza que muitos de vocês terão maneiras mais inteligentes para mim :-) Aqui, é claro, só vejo os valores mais Minus.

Para obter o primeiro valor:

cat /tmp/pwpower.log |grep -o "\-.*" | head -n 1

Para obter o segundo valor:

cat /tmp/pwpower.log |grep -o "\-.*" | tail -n1

E pergunta relacionada, existe uma maneira simples de pegar essas STRINGs e transformar para que eu possa calcular o SUM?

Respostas:


12

Todos os valores:

$ awk -F '[ -]*' '$0=$NF' /tmp/pwpower.log
114.10
130.09

Valor na primeira linha:

$ awk -F '[ -]*' 'NR==1{print $NF;exit}' /tmp/pwpower.log
114.10

Valor na segunda linha:

$ awk -F '[ -]*' 'NR==2{print $NF;exit}' /tmp/pwpower.log
130.09

Soma de todos os valores:

$ awk -F '[ -]*' '{sum+=$NF} END{print sum}' /tmp/pwpower.log
244.19

1
Seu FS não precisa ser tão complicado: -F-será suficiente .
Glenn Jackman

Para entradas mais complexas, se você não souber se os campos anteriores têm espaços, use uma vírgula como separador de campos e execute a coisa toda tr -d "- "primeiro.
Jason C

@glennjackman A maneira como interpreto a questão é que o valor pode ser não negativo (sem geração), o que é justo -F-.
Adrian Frühwirth

Na verdade, eu não tinha lido isso de perto.
Glenn Jackman

8

Você pode usar cutpara selecionar a segunda coluna de números e paste -sd+criar uma série de números para adicionar. A ferramenta bcpode ser usada para fazer o cálculo.

$ cut -d',' -f2 pwpower.log | paste -sd+ | bc
-244.19

Como funciona

Seleciona os números da 2ª coluna.

$ cut -d',' -f2 pwpower.log 
 -114.10
 -130.09

Re-formata-os em uma única linha com um +sinal entre cada número:

$ cut -d',' -f2 pwpower.log | paste -sd+
 -114.10+ -130.09

Executa o cálculo:

$ cut -d',' -f2 pwpower.log | paste -sd+ | bc
-244.19

Para obter o valor absoluto:

$ cut -d',' -f2 pwpower.log | sed 's/-//g' | paste -sd+ | bc
244.19

Se o formato do arquivo pwpower.logestiver garantido, você poderá cutomitir o sinal de menos:

$ cut -d'-' -f2 pwpower.log | paste -sd+ | bc
244.19

6

Uma abordagem do KISS

$ awk '{print -$2; t+=-$2}; END{print t}' pwpower.log 
114.1
130.09
244.19

1
BEIJO? O que é isso?
Bernhard

Mantendo-o simples e estúpido;) #
steeldriver

@sim sim, mas a menos que eu descaracterizou, o OP pediu especificamente para o sinal a ser removido
steeldriver

@ steeldriver - ah sim, meu mal, eu perdi a frase enterrada lá.
slm

4
Mantenha simples, idiota. Para sugerir que quando você não simplifica, você está sendo estúpido.
Matt

4

Eu gosto do seu comando grep, mas poderia ser melhorado para remover o sinal de menos e funcionar nos casos em que não há sinal de menos. Expressões regulares estendidas disponíveis no GNU grep com a -Ebandeira nos permitem corresponder um número com mais precisão.

É um pouco mais eficiente não usar cat, mas passe o nome do arquivo como argumento para o primeiro comando e deixe-o ler o arquivo. Também me ocorre que, se você estiver lidando apenas com a primeira ou a última linha do arquivo, faz mais sentido usar os comandos headou tailprimeiro, para que você só precise combinar uma linha grep.

Primeiro valor:

$ head -n 1 /tmp/pwpower.log | grep -oE '[0-9\.]+$' 
114.10

Último valor:

$ tail -n 1 /tmp/pwpower.log | grep -oE '[0-9\.]+$'
130.09

Soma (com o comando awk daqui ):

$ grep -oE '[0-9\.]+$' /tmp/pwpower.log | awk '{s+=$1} END {print s}'
244.19

3
[root@ip-10-186-149-181 ~]# cut -d '-' -f2 /tmp/pwpower.log | paste -sd+ | bc
244.19

Isso fará o cálculo sem o sinal de menos.

Eu acho que o corte é mais rápido que o awk, em geral


1

awké a ferramenta certa, mas o número provavelmente pode ser positivo (certo?), o que significa que você não deseja usar o sinal de menos como um separador de campos. Em vez disso, use a vírgula como separador de campos e, em seguida, negue numericamente cada valor - awkconverterá automaticamente as strings em números para você:

$ awk -F, '{ print -$2 }' < /tmp/pwpower.log
114.1
130.09

Se houver algum número positivo, eles sairão negativos. Se você deseja apenas a soma, awkpode fazer isso também:

$ awk -F, '{ sum += -$2 } END { print sum }' < /tmp/pwpower.log
244.19

No awk, você pode usar sqrt($2^2)como um truque para obter valor absoluto.
Jason C

@JasonC Isso é inteligente, mas no contexto acredito que seria a coisa errada a se fazer.
Zwol

0

Para somar os dois valores:

(awk -F- '{printf "%s+", $2}' /tmp/pwpower.log; echo 0) | bc -l

Isso tudo é um pouco redundante. Por que nog terra usar as opções de cálculo de awk?
Bernhard

1
Sim, é verdade, mas eu gosto bc=)
caos

1
Ohw, bem, então por que usar awk? echo $(cut -d- -f2 file | tr '\n' '+')0 | bc
Bernhard

@ Bernhard Bem, por que usar cut? Em [insert_cmd_here]vez disso, use , gere um loop de sub-invólucro, invente novas matemáticas, use um agrupamento humano ou aritmética mental, canalize meus pensamentos bc. Por que fazemos as coisas? Não há razão para tornar minha resposta ruim.
caos

0

Você também pode usar sed

$-sed -r 's/[^-]+.(.*)/\1/g' /tmp/pwpower.log
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.