如何按特定顺序 grep 两个字符串并根据我的 grep 逐行计算值

如何按特定顺序 grep 两个字符串并根据我的 grep 逐行计算值

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

相关内容