Ich habe diesen Code in einem Shell-Skript:
sort input | uniq -c | sort -nr > output
Die Eingabedatei hatte keine vorhergehenden Leerzeichen, die Ausgabe jedoch. Wie behebe ich das? Dies ist in Bash
Ich habe diesen Code in einem Shell-Skript:
sort input | uniq -c | sort -nr > output
Die Eingabedatei hatte keine vorhergehenden Leerzeichen, die Ausgabe jedoch. Wie behebe ich das? Dies ist in Bash
Antworten:
Das Standardverhalten von uniq besteht darin, die Häufigkeit in einer 7 Felder breiten Zeile rechtsbündig auszurichten und dann die Häufigkeit durch ein einzelnes Leerzeichen vom Element zu trennen.
Quelle: https://www.thelinuxrain.com/articles/tweaking-uniq-c
Entfernen Sie die führenden Leerzeichen mit sed:
$ sort input | uniq -c | sort -nr | sed 's/^\s*//' > output
FWIW können Sie für mehr Flexibilität ein anderes Sortierwerkzeug verwenden. Python ist ein solches Werkzeug.
#!/usr/bin/python3
import sys, operator, collections
counter = collections.Counter(map(operator.methodcaller('rstrip', '\n'), sys.stdin))
for item, count in counter.most_common():
print(count, item)
Theoretisch wäre dies sogar schneller als das sort
Tool für große Eingaben, da das obige Programm eine Hash-Tabelle verwendet, um doppelte Zeilen anstelle einer sortierten Liste zu identifizieren. (Leider werden Zeilen mit identischer Anzahl in einer beliebigen statt in einer natürlichen Reihenfolge angeordnet. Dies kann geändert werden und ist immer noch schneller als zwei sort
Aufrufe.)
Wenn Sie mehr Flexibilität auf dem Ausgabeformat möchten , können Sie in der Suche print()
und format()
integrierte Funktionen.
Wenn Sie beispielsweise die Zählzahl in Oktalform mit bis zu 7 führenden Nullen und gefolgt von einem Tabulator anstelle eines Leerzeichens mit einem NUL-Zeilenabschluss drucken möchten, ersetzen Sie die letzte Zeile durch:
print(format(count, '08o'), item, sep='\t', end='\0')
Speichern Sie das Skript beispielsweise in einer Datei sort_count.py
und rufen Sie es mit Python auf:
python3 sort_count.py < input
uniq -c -i | tr -s ' ' | cut -c 2-
Übersetzen Sie führende Leerzeichen mit tr -s in einzelne Leerzeichen und drucken Sie dann die Ausgabe des 2. Zeichens mit cut -c aus.