Dlaczego polecenie uniq -c umieściło spację na początku?


11

Mam ten kod w skrypcie powłoki:

sort input | uniq -c | sort -nr > output

Plik wejściowy nie zawierał wcześniejszych białych znaków, ale dane wyjściowe mają. Jak to naprawić? To jest bash

Odpowiedzi:


13

Domyślne zachowanie uniq polega na uzasadnieniu częstotliwości w linii o szerokości 7 spacji, a następnie oddzieleniu częstotliwości od elementu pojedynczą spacją.

Źródło: https://www.thelinuxrain.com/articles/tweaking-uniq-c

Usuń wiodące spacje za pomocą sed:

$ sort input | uniq -c | sort -nr | sed 's/^\s*//' > output

2
7 spacji, czyli „tylko mniej niż tab”.
Chrylis -on strike-

Następnie możesz rozdzielić tabulatorami czymś takim perl -pe 's/ *(\d+) /$1\t/'( tutaj kilka alternatyw ). Ruruj do schowka, xclip -selection caby wkleić bezpośrednio do arkusza kalkulacyjnego.
Pablo Bianchi

5

uniq -cdodaje wiodące białe znaki. Na przykład

$ echo test
test
$ echo test | uniq -c
      1 test

Możesz dodać polecenie na końcu potoku, aby je usunąć. Na przykład

$ echo test | uniq -c | sed 's/^\s*//'
1 test

1

FWIW możesz użyć innego narzędzia do sortowania dla większej elastyczności. Python jest jednym z takich narzędzi.

Źródło

#!/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)

Teoretycznie byłoby to nawet szybsze niż sortnarzędzie do dużych danych wejściowych, ponieważ powyższy program używa tabeli skrótów do identyfikacji duplikatów linii zamiast posortowanej listy. (Niestety, umieszcza wiersze o identycznej liczbie w arbitralnym, a nie naturalnym porządku; można to zmienić i nadal być szybsze niż dwie sortinwokacje).

Format wyjściowy

Jeśli chcesz więcej elastyczności na format wyjściowy można przyjrzeć się print()i format()wbudowanych funkcji.

Na przykład, jeśli chcesz wydrukować liczbę ósemkową z maksymalnie 7 zerami wiodącymi, a następnie znakiem tabulacji zamiast znaku spacji z zakończeniem linii NUL, zamień ostatni wiersz na:

    print(format(count, '08o'), item, sep='\t', end='\0')

Stosowanie

Zapisz skrypt w pliku, powiedzmy sort_count.py, i wywołaj go za pomocą Pythona:

python3 sort_count.py < input

0
uniq -c -i | tr -s ' ' | cut -c 2-

Przetłumacz wiodące białe znaki na pojedyncze białe znaki za pomocą tr -s, a następnie wydrukuj wynik od drugiego znaku za pomocą cut -c.


Twoje rozwiązanie wyciska wszystkie wystąpienia sekwencji białych znaków. To jest pożądany efekt.
Marc Vanhoomissen
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.