Ich habe eine Liste von Nummern in einer Datei, eine pro Zeile. Wie kann ich den Minimal-, Maximal-, Median- und Durchschnittswert ermitteln ? Ich möchte die Ergebnisse in einem Bash-Skript verwenden.
Obwohl meine unmittelbare Situation Ganzzahlen betrifft, wäre eine Lösung für Gleitkommazahlen auf der ganzen Linie nützlich, aber eine einfache Ganzzahlmethode ist in Ordnung.
bash
awk
arithmetic
bc
Peter.O
quelle
quelle
Antworten:
Sie können die Programmiersprache R verwenden .
Hier ist ein schnelles und schmutziges R-Skript:
Beachten Sie die
"stdin"
inscan
die ein spezielles Dateiname ist von der Standardeingabe zu lesen (das heißt , aus Rohren oder Umleitungen).Jetzt können Sie Ihre Daten über stdin an das R-Skript umleiten:
Funktioniert auch für Gleitkommazahlen:
Wenn Sie keine R-Skriptdatei schreiben möchten, können Sie in der Befehlszeile einen echten Einzeiler (mit Zeilenumbruch nur zur besseren Lesbarkeit) aufrufen, indem Sie Folgendes verwenden
Rscript
:Lesen Sie die feinen R-Handbücher unter http://cran.r-project.org/manuals.html .
Leider ist die vollständige Referenz nur als PDF verfügbar. Eine andere Möglichkeit, die Referenz zu lesen, besteht
?topicname
darin, die Eingabeaufforderung einer interaktiven R-Sitzung einzugeben.Der Vollständigkeit halber gibt es einen R-Befehl, der alle gewünschten Werte und mehr ausgibt. Leider in einem menschenfreundlichen Format, das sich programmgesteuert nur schwer analysieren lässt.
quelle
r-base
.R
Sprache ist in dieser Situation eindeutig das Beste für meine Anforderung. Laut Gilles 'Antwort ist dieRscript
Schnittstelle zu Skriptdateien am besten geeignet (im GegensatzR
zur interaktiven Schnittstelle) ... und R im Terminal ist ein praktischer Taschenrechner , oder Testumgebung (wie Python :)cat datafile | Rscript -e 'print(summary(scan("stdin")));'
Ich verwende ein kleines awk-Programm, um die Summe, die Datenanzahl, das minimale Datum, das maximale Datum, den Mittelwert und den Median einer einzelnen Spalte numerischer Daten (einschließlich negativer Zahlen) anzugeben:
Das obige Skript liest von stdin und druckt tabulatorgetrennte Ausgabespalten in einer einzelnen Zeile.
quelle
NR==1
gehen kann (eine nutzlose Verwendung von if) zusammen mit den min / max Checks, damit alle Initialisierungen in der BEGIN Sektion liegen (gut!) ... Kommentareawk
wird davon ausgegangen, dass "neue" Variablen Null sind, sodass in diesem Fall derBEGIN{}
Abschnitt nicht erforderlich ist. Ich habe den Zeilenumbruch behoben (es ist auch nicht nötig, die Zeilenumbrüche zu umgehen). Ich habe auchOFS="\t"
dieprint
Zeile aufgeräumt und den zweiten Kommentar von @ Peter.O implementiert. (Ja, meine Regex erlaubt.
, aber alsawk
interpretiert das als0
, das ist akzeptabel.)awk
Skript ist jetzt wesentlich anders. Ich habe fast das Gefühl, Sie sollten das obige Programm anerkennen, um Kredit zu geben, wo Kredit fällig ist.Mit GNU Datamash :
quelle
brew install datamash
gibt dir eine funktionierende Version für macOS, wenn du Hombrew installiert hast.Min, Max und Mittel sind mit awk ziemlich einfach zu bekommen:
Das Berechnen des Medians ist etwas kniffliger, da Sie Zahlen sortieren und eine Weile speichern müssen oder sie zweimal lesen müssen (erstens, um sie zu zählen, zweitens, um den Medianwert zu erhalten). Hier ist ein Beispiel, in dem alle Zahlen gespeichert sind:
quelle
asort
anstatt der Piped verwendetsort
Hier ist ein Link zu meiner resultierenden Version paste.ubuntu.com/612674 ... (Und ein Hinweis an Kim: Ich habe jetzt seit ein paar Stunden mit awk experimentiert Die Arbeit mit einem Beispiel für persönliches Interesse ist für mich viel besser. je kompakter desto besser. Ich werde eine Weile warten ...Pythonpy funktioniert gut für diese Art von Dingen:
quelle
Minimum:
Maximal:
Median:
Durchschnittlich:
Mit
jq
der Option-s
(--slurp
) wird ein Array für die Eingabezeilen erstellt, nachdem jede Zeile als JSON oder in diesem Fall als Zahl analysiert wurde.quelle
quelle
echo file.txt
sieht vielleicht nicht ganz richtig auscat
Und ein Perl-Einzeiler (lang), einschließlich Median:
Die speziellen Optionen sind:
-0777
: Lesen Sie die gesamte Datei auf einmal statt Zeile für Zeile-a
: Autosplit in das @F-ArrayEine besser lesbare Skriptversion desselben wäre:
Wenn Sie Dezimalstellen wünschen, ersetzen Sie diese
%d
durch etwas wie%.2f
.quelle
Simple-r ist die Antwort:
Es verwendet R-Umgebung, um die statistische Analyse zu vereinfachen.
quelle
Nur um eine Vielzahl von Optionen auf dieser Seite vorzustellen, gibt es zwei weitere Möglichkeiten:
1: Oktave
Hier ist ein kurzes Oktavbeispiel.
2: bash + einzweckwerkzeuge .
Dieses Skript verwendet
numprocess
undnumaverage
from package, damit bash Gleitkommazahlen verarbeitetnum-utils
.PS. Ich habe auch einen vernünftigen Blick darauf geworfen
bc
, aber für diesen speziellen Job bietet es nichts, was über das hinausgeht, was esawk
tut. Es ist (wie das 'c' in 'bc' angibt) ein Taschenrechner - ein Taschenrechner, der viel Programmierung erfordert,awk
und dieses Bash-Skript ...quelle
Ich werde Lesmanas Wahl von R überholen und mein erstes R-Programm anbieten. Es liest eine Zahl pro Zeile in der Standardeingabe und schreibt vier durch Leerzeichen getrennte Zahlen (min, max, average, median) in die Standardausgabe.
quelle
R
es sich um die interaktive Schnittstelle handelt, undRscript
die Skriptdateien steuert, die gemäß Ihrem Beispiel-Hash-Bang ausführbar sein können , oder innerhalb eines Bash-Skripts aufgerufen. Die Skripts können Befehlszeilenargumente verarbeiten (z. B. stackoverflow.com/questions/2045706/… ), sodass sie gut aussehen ... Auch R-Ausdrücke können in Bash über-e
... verwendet werden Ich frage mich, wie imR
Vergleich zubc
...Das Folgende
sort
/awk
Tandem macht es:(Der Median wird als Mittelwert der beiden zentralen Werte berechnet, wenn die Anzahl der Werte gerade ist.)
quelle
In Anlehnung an den Code von Bruce wird hier eine effizientere Implementierung vorgestellt, bei der nicht alle Daten im Speicher bleiben. Wie in der Frage angegeben, wird davon ausgegangen, dass die Eingabedatei (höchstens) eine Nummer pro Zeile enthält. Es werden die Zeilen in der Eingabedatei gezählt, die eine qualifizierende Nummer enthalten, und die Zählung wird
awk
zusammen mit den sortierten Daten (vor) dem Befehl übergeben. So zum Beispiel, wenn die Datei enthältdann ist die Eingabe
awk
tatsächlichDann
awk
erfasst das Skript die Datenanzahl imNR==1
Codeblock und speichert den Mittelwert (oder die beiden Mittelwerte, die gemittelt werden, um den Median zu ergeben), wenn sie angezeigt werden.quelle
cat
Befehle haben. siehe UUOC . … (Fortsetzung)FILENAME
und wissen, auf was Sie ihn festgelegt haben. Im Allgemeinen sollten Sie jedoch immer Shell-Variablen angeben, es sei denn, Sie haben einen guten Grund, dies nicht zu tun Sicher, Sie wissen, was Sie tun. (4) Sowohl Ihre Antwort als auch die von Bruce ignorieren negative Eingaben (dh Zahlen, die mit beginnen-
); Es gibt nichts in der Frage, was darauf hindeutet, dass dies das richtige oder gewünschte Verhalten ist. Fühle dich nicht schlecht; Es ist über vier Jahre her und anscheinend bin ich die erste Person, die es bemerkt hat.cat
und der Erklärung hinzugefügt.Das
num
ist eine winzigeawk
Hülle, die genau dies und mehr leistet, zEs erspart Ihnen die Neuerfindung des Rades in der ultra-portablen awk. Die Dokumente sind oben angegeben und der direkte Link hier (siehe auch die GitHub-Seite ).
quelle
Mit
perl
:quelle
cat/python
Einzige Lösung - kein Leereingabesicher!quelle
Wenn Sie sich mehr für Nützliches als für Coolness oder Cleveres interessieren,
perl
ist die Wahl einfacher alsawk
. Im Großen und Ganzen wird es auf jedem * nix mit konsistentem Verhalten sein und ist einfach und kostenlos unter Windows zu installieren. Ich denke, es ist auch weniger kryptisch alsawk
, und es wird einige Statistikmodule geben, die Sie verwenden könnten, wenn Sie zwischen dem Schreiben selbst und etwas wie R ein Halfway-House wollen Esperl
dauerte ungefähr eine Minute, bis das Skript geschrieben war, und ich schätze, der einzige kryptische Teil wäre derwhile(<>)
, der eine sehr nützliche Abkürzung darstellt diese Zeile in der speziellen Variablen$_
. Sie können dies also in eine Datei mit dem Namen count.pl einfügen und als ausführenperl count.pl myfile
. Abgesehen davon sollte es schmerzlich offensichtlich sein, was los ist.quelle
quelle
sh
) als Interpreter verwendet wird. Es gibt auch ein Problem damit, wie die Daten aus der Datei in das Array eingelesen werden.