
假設我有 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