
人間が読めるように編集した 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"},
** 以前の形式のすべてのテキストファイル **
yes
だから、最初の行とno
2番目の行を含む行をgrepしたいのです
出力は次のようになると予想しています
出力
{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},
単語の順序で grep する方法をまだ見つけることができませんでした。
2番目の質問は私の出力に関するものです。
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です...そのデータ構造を乱雑にしてはいけません
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
が、間に何があるのかわからない場合は、.*
空白以外の文字を 0 回以上繰り返して一致させるために を使用します。出力 (入力ファイルを使用):
$ 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