
Ich habe folgende Ausgabe:
2015/1/7 8
2015/1/8 49
2015/1/9 40
2015/1/10 337
2015/1/11 11
2015/1/12 3
2015/1/13 9
2015/1/14 102
2015/1/15 62
2015/1/16 10
2015/1/17 30
2015/1/18 30
2015/1/19 1
2015/1/20 3
2015/1/21 23
2015/1/22 12
2015/1/24 6
2015/1/25 3
2015/1/27 2
2015/1/28 16
2015/1/29 1
2015/2/1 12
2015/2/2 2
2015/2/3 1
2015/2/4 10
2015/2/5 13
2015/2/6 2
2015/2/9 2
2015/2/10 25
2015/2/11 1
2015/2/12 6
2015/2/13 12
2015/2/14 2
2015/2/16 8
2015/2/17 8
2015/2/20 1
2015/2/23 1
2015/2/27 1
2015/3/2 3
2015/3/3 2
Und ich möchte ein Histogramm zeichnen
2015/1/7 ===
2015/1/8 ===========
2015/1/9 ==========
2015/1/10 ====================================================================
2015/1/11 ===
2015/1/11 =
...
Wissen Sie, ob es einen Bash-Befehl gibt, mit dem ich das tun kann?
Antwort1
In perl
:
perl -pe 's/ (\d+)$/"="x$1/e' file
e
bewirkt, dass der Ausdruck ausgewertet wird, sodass ich ihn=
mit dem Wert von$1
(der mit übereinstimmenden Zahl(\d+)
) wiederholt bekomme.- Sie könnten
"="x($1\/3)
anstelle von verwenden"="x$1
, um kürzere Zeilen zu erhalten. (Das/
wird maskiert, da wir uns mitten in einem Ersetzungsbefehl befinden.)
In bash
(inspiriert vondiese SO-Antwort):
while read d n
do
printf "%s\t%${n}s\n" "$d" = | tr ' ' '='
done < test.txt
printf
füllt die zweite Zeichenfolge mit Leerzeichen auf, um eine Breite von$n
(%${n}s
) zu erhalten, und ich ersetze die Leerzeichen durch=
.- Die Spalten werden durch einen Tabulator (
\t
) abgegrenzt, Sie können es aber schöner gestalten, indem Sie eine Weiterleitung an durchführencolumn -ts'\t'
. - Sie können
$((n/3))
anstelle von verwenden${n}
, um kürzere Zeilen zu erhalten.
Andere Version:
unset IFS; printf "%s\t%*s\n" $(sed 's/$/ =/' test.txt) | tr ' ' =
Der einzige Nachteil, den ich sehe, ist, dass Sie sed
die Ausgabe von irgendwohin weiterleiten müssen, wenn Sie verkleinern möchten, ansonsten ist dies die sauberste Option. Wenn die Möglichkeit besteht, dass Ihre Eingabedatei eines davon enthält, [?*
sollten Sie den Befehl mit / einleiten set -f;
.
Antwort2
Versuchen Sie dies inperl:
perl -lane 'print $F[0], "\t", "=" x ($F[1] / 5)' file
ERKLÄRUNGEN:
-a
ist ein explizitessplit()
In-@F
Array, erhalten wir die Werte mit$F[n]
x
besteht darin, Perl anzuweisen, ein Zeichen N-mal zu drucken.($F[1] / 5)
: hier erhalten wir die Zahl und dividieren sie durch 5 für eine schöne Druckausgabe (einfache Arithmetik)
Antwort3
Einfach mitawk
awk '{$2=sprintf("%-*s", $2, ""); gsub(" ", "=", $2); printf("%-10s%s\n", $1, $2)}' file
2015/1/7 ========
2015/1/8 =================================================
2015/1/9 ========================================
..
..
Oder mit meiner Lieblingsprogrammiersprache
python3 -c 'import sys
for line in sys.stdin:
data, width = line.split()
print("{:<10}{:=<{width}}".format(data, "", width=width))' <file
Antwort4
So etwas könnte man machen mit demBarVerb inMüller
$ mlr --nidx --repifs --ofs tab bar -f 2 file
2015/1/7 ***.....................................
2015/1/8 *******************.....................
2015/1/9 ****************........................
2015/1/10 ***************************************#
2015/1/11 ****....................................
2015/1/12 *.......................................
.
.
.