Wie greppt man zwei Strings in einer Zeile in einer bestimmten Reihenfolge UND berechnet die Werte zeilenweise gemäß meinem Grep

Wie greppt man zwei Strings in einer Zeile in einer bestimmten Reihenfolge UND berechnet die Werte zeilenweise gemäß meinem Grep

Nehmen wir an, ich habe einen Python-Wörterbuchtext, den ich so bearbeitet habe, dass er für Menschen lesbar ist. Er steht jetzt Zeile für Zeile wie die folgende Eingabe.

Eingang

{"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"},

** ALLE TEXTDATEIEN IM VORHERIGEN FORMAT **

Ich möchte also nach Zeilen greppen, die yesin der ersten und noin der zweiten Zeile enthalten sind.

Ich erwarte also eine Ausgabe wie diese

Ausgabe

{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},

Ich konnte bisher keine Möglichkeit finden, nach Wortreihenfolge zu greppen.

Und meine zweite Frage betrifft meine Ausgabe?

Kann ich awk sumdie Funktion verwenden, um die Gesamtzahl der Stimmen zu berechnen? Diese sollte 4,1aus der Ausgabe stammen.

Antwort1

Überprüfen Sie dies:

Benötigte Zeilen drucken

awk -F'[,:]' ' 
$4 ~ "yes" && $8 ~ "no" {
    print;
}' input.txt

Ausgabe

{"case":"0901","emailed":"yes","vote":1,"accepted":"no"},
{"case":"0090","emailed":"yes","vote":3,1"accepted":"no"},

Summe berechnen

awk -F'[,:]' ' 
$4 ~ "yes" && $8 ~ "no" {
    sum += $6"."$7;
}
END {
    print sum;
}' input.txt

Ausgabe

4.1

Antwort2

Ich habe Python-Wörterbuchtext

Die richtigePythonWörterbuch wiederherstellen/verarbeiten:

Meine Botschaft ist: Python ist Python ... Sie sollten seine Datenstrukturen nicht verfälschen

recover_dict.pySkript:

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)

Verwendung:

python recover_dict.py file

Die Ausgabe:

{'case': '0901', 'vote': 1, 'accepted': 'no', 'emailed': 'yes'}
{'case': '0090', 'vote': 3.1, 'accepted': 'no', 'emailed': 'yes'}
4.1

Antwort3

Etwas wie

grep 'yes.*no' yourfile \
    | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' \
    | paste -sd+ | bc

sollte für Sie funktionieren.

Erläuterung

  • grep 'yes.*no' yourfile

Wenn Sie die Reihenfolge der Wörter angeben möchten grep, aber nicht wissen, was dazwischen steht, verwenden Sie , .*um alle Zeichen außer Leerzeichen abzugleichen, die null oder mehrmals wiederholt werden. Ausgabe (mit Ihrer Eingabedatei):

$ 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'

Findet eine Übereinstimmung mit einer Zahl (Ziffern und möglicherweise ,), wenn ...vote":in der Ausgabe von grepoben eins vorangestellt ist, und ersetzt es ,durch .. Ausgaben

$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g'
1.
3.1
  • paste -sd+

Ersetzt die neue Zeile zwischen Ihren Zahlen durch +, gibt aus:

$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+
1.+3.1
  • bc

Führt die obige Operation aus ( 1.+3.1), gibt aus:

$ grep 'yes.*no' inputfile | sed -e 's/.*vote":\([0-9,]\+\).*/\1/g' -e 's/,/./g' | paste -sd+ | bc
4.1

verwandte Informationen