
Digamos que tengo un texto de diccionario de Python que edité para que sea legible por humanos. por lo que ahora es línea por línea como la siguiente entrada.
Aporte
{"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 EL ARCHIVO DE TEXTO EN EL FORMATO ANTERIOR**
Entonces me gustaría buscar líneas que incluyan yes
la primera y no
la segunda
Entonces espero que el resultado sea así.
Producción
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
Todavía no pude encontrar una manera de buscar por orden de palabras.
¿Y mi segunda pregunta es sobre mi resultado?
¿Puedo usar awk
sum
la función para calcular el total de votos? que debería ser 4,1
de la salida.
Respuesta1
Mira esto:
Imprimir líneas necesarias
awk -F'[,:]' '
$4 ~ "yes" && $8 ~ "no" {
print;
}' input.txt
Producción
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
Calculando la suma
awk -F'[,:]' '
$4 ~ "yes" && $8 ~ "no" {
sum += $6"."$7;
}
END {
print sum;
}' input.txt
Producción
4.1
Respuesta2
Tengo texto de diccionario de Python.
El correctoPitónrecuperación/procesamiento del diccionario:
Mi mensaje es: Python es Python... no deberías distorsionar sus estructuras de datos
recover_dict.py
guion:
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
La salida:
{'case': '0901', 'vote': 1, 'accepted': 'no', 'emailed': 'yes'}
{'case': '0090', 'vote': 3.1, 'accepted': 'no', 'emailed': 'yes'}
4.1
Respuesta3
Algo como
grep 'yes.*no' yourfile \
| sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' \
| paste -sd+ | bc
debería funcionar para ti.
Explicación
grep 'yes.*no' yourfile
Si desea grep
ordenar las palabras, pero no sabe qué hay entre ellas, utilice .*
para hacer coincidir cualquier carácter que no sea un espacio en blanco repetido cero o más veces. Salida (con su archivo 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'
Haga coincidir un número (dígitos y posiblemente ,
), si está precedido por ...vote":
en el resultado grep
anterior, y sustitúyalo ,
por .
. Salidas
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g'
1.
3.1
paste -sd+
Sustituye la nueva línea entre tus números con +
, genera:
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+
1.+3.1
bc
Ejecuta la operación anterior ( 1.+3.1
), genera:
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+ | bc
4.1