Почему эта команда поставила пробел в начале?
У меня есть этот код в сценарии оболочки:
sort input | uniq -c | sort -nr > output
Во входном файле не было предшествующих пробелов, а в выходных. Как это исправить? Это в баш
3 ответа
Поведение uniq по умолчанию состоит в том, чтобы выровнять по правому краю частоту в строке шириной 7 пробелов, а затем отделить частоту от элемента одним пробелом.
Источник: https://www.thelinuxrain.com/articles/tweaking-uniq-c
Удалите ведущие пробелы с помощью sed:
$ sort input | uniq -c | sort -nr | sed 's/^\s*//' > output
uniq -c
добавляет ведущие пробелы. Например
$ echo test
test
$ echo test | uniq -c
1 test
Вы можете добавить команду в конце конвейера, чтобы удалить ее. Например
$ echo test | uniq -c | sed 's/^\s*//'
1 test
FWIW вы можете использовать другой инструмент сортировки для большей гибкости. Python является одним из таких инструментов.
Источник
#!/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)
В теории это было бы даже быстрее, чем sort
инструмент для больших входов, так как вышеупомянутая программа использует хеш-таблицу для идентификации дублирующих строк вместо отсортированного списка. (Увы, он размещает строки с одинаковым количеством в произвольном, а не в естественном порядке; это можно изменить, но все равно будет быстрее, чем два sort
вызовы.)
Выходной формат
Если вы хотите больше гибкости в выходном формате, вы можете посмотреть в print()
а также format()
встроенные функции.
Например, если вы хотите вывести число в восьмеричной системе счисления с числом начальных нулей до 7, за которым следует символ табуляции вместо пробела с символом конца строки NUL, замените последнюю строку на:
print(format(count, '08o'), item, sep='\t', end='\0')
использование
Сохраните сценарий в файле, скажем sort_count.py
и вызвать его с помощью Python:
python3 sort_count.py < input
uniq -c -i | tr -s ' ' | cut -c 2-
Преобразуйте ведущие пробелы в одиночные пробелы с помощью tr -s, а затем распечатайте вывод 2-го символа с помощью cut -c.