假设我有 Python 字典文本,我将其编辑为人类可读的。所以现在它是逐行作为以下输入。
输入
{"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"},
** 所有文本文件均采用先前格式 **
所以我想 grep 包含yes
第一个和no
第二个的行
所以我期望输出是这样的
输出
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
我还无法找到一种按单词顺序 grep 的方法。
我的第二个问题是关于我的输出?
我是否可以使用awk
sum
函数来计算投票总数?这应该4,1
来自输出。
答案1
检查一下:
打印所需线条
awk -F'[,:]' '
$4 ~ "yes" && $8 ~ "no" {
print;
}' input.txt
输出
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
计算总和
awk -F'[,:]' '
$4 ~ "yes" && $8 ~ "no" {
sum += $6"."$7;
}
END {
print sum;
}' input.txt
输出
4.1
答案2
我有 python 字典文本
正确的Python字典恢复/处理:
我的信息是:Python 就是 Python ...你不应该弄乱它的数据结构
recover_dict.py
脚本:
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)
用法:
python recover_dict.py file
输出:
{'case': '0901', 'vote': 1, 'accepted': 'no', 'emailed': 'yes'}
{'case': '0090', 'vote': 3.1, 'accepted': 'no', 'emailed': 'yes'}
4.1
答案3
就像是
grep 'yes.*no' yourfile \
| sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' \
| paste -sd+ | bc
应该为你工作。
解释
grep 'yes.*no' yourfile
如果您想grep
按单词顺序排列,但不知道单词之间的内容,请使用.*
来匹配任何重复零次或多次的非空白字符。输出(带有您的输入文件):
$ 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'
如果上面的输出中,
前面有,则匹配一个数字(数字和可能的) ,并替换为。输出...vote":
grep
,
.
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g'
1.
3.1
paste -sd+
用 , 替换数字之间的换行符+
,输出:
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+
1.+3.1
bc
执行上面的操作(1.+3.1
),输出:
$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+ | bc
4.1