
Digamos que eu tenha um texto de dicionário Python que editei para ser legível por humanos. então agora é linha por linha como a seguinte entrada.
Entrada
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0908","emailed":"yes","vote":8,1"accepted":"yes"},
{"case":"0911","emailed":"no","vote":10,1"accepted":"yes"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
** TODO O ARQUIVO DE TEXTO NO FORMATO ANTERIOR **
Então, eu gostaria de usar grep nas linhas que incluem yes
o primeiro e no
o segundo
Então, estou esperando que a saída seja assim
Saída
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
Ainda não consegui encontrar uma maneira de usar o grep por ordem de palavras.
E minha segunda pergunta é em relação à minha produção?
se eu puder usar awk
sum
a função para calcular o total de votos? que deve ser 4,1
da saída.
Responder1
Verifique isto:
Imprimindo as linhas necessárias
awk -F'[,:]' '
$4 ~ "yes" && $8 ~ "no" {
print;
}' input.txt
Saída
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
Calculando soma
awk -F'[,:]' '
$4 ~ "yes" && $8 ~ "no" {
sum += $6"."$7;
}
END {
print sum;
}' input.txt
Saída
4.1
Responder2
Eu tenho texto de dicionário python
O adequadoPitãorecuperação/processamento de dicionário:
Minha mensagem é: Python é Python... você não deve distorcer suas estruturas de dados
recover_dict.py
roteiro:
import sys, re, ast
with open(sys.argv[1], 'r') as f:
items = ast.literal_eval(re.sub(r"(\d+),(\d+)", "\\1.\\2,", f.read().replace('\n','')))
sum = 0
for d in items:
if d['emailed'] == 'yes' and d['accepted'] == 'no':
sum += d['vote']
print(d)
print(sum)
Uso:
python recover_dict.py file
A saída:
{'case': '0901', 'vote': 1, 'accepted': 'no', 'emailed': 'yes'}
{'case': '0090', 'vote': 3.1, 'accepted': 'no', 'emailed': 'yes'}
4.1
Responder3
Algo como
grep 'yes.*no' yourfile \
| sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' \
| paste -sd+ | bc
deve funcionar para você.
Explicação
grep 'yes.*no' yourfile
Se você quiser grep
ordenar as palavras, mas não sabe o que há entre elas, use .*
para corresponder a qualquer caractere que não seja espaço em branco repetido zero ou mais vezes. Saída (com seu arquivo de entrada):
$ grep 'yes.*no' inputfile
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"}
sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g'
Combine um número (dígitos e possivelmente ,
), se precedido por ...vote":
na saída acima grep
, e substitua ,
por .
. Resultados
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g'
1.
3.1
paste -sd+
Substitui a nova linha entre seus números por +
, gera:
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+
1.+3.1
bc
Executa a operação acima ( 1.+3.1
), gera:
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+ | bc
4.1