Почему вывод uniq -c с пробелом вместо \t?

Я использую uniq -c какой-то текстовый файл. Его вывод выглядит следующим образом:

123(space)first word(tab)other things
  2(space)second word(tab)other things

....

Поэтому мне нужно извлечь общее число (например, 123 и 2 выше), но я не могу понять, как это сделать, потому что, если я разделю эту строку пробелом, она будет похожа на ['123', 'first', 'word(tab)other', 'things']. Я хочу знать, почему он не выводится с вкладкой?

И как извлечь общее число в оболочке? (Я наконец извлек его с помощью python, WTF)

Обновление: извините, я неправильно описал свой вопрос. Я не хотел суммировать общее число, я просто хочу заменить (пробел) на (табуляцию), но это не влияет на пробел в словах, потому что мне все еще нужны данные после. Именно так:

123(tab)first word(tab)other things
  2(tab)second word(tab)other things

person MoreFreeze    schedule 26.07.2012    source источник
comment
Вкладка - это не пробел, поэтому awk правильный.   -  person    schedule 26.07.2012
comment
@Tichodroma нет, ты не следил за мной. Я имею в виду, что если я разделю строку по пробелу, я не смогу правильно получить данные.   -  person MoreFreeze    schedule 26.07.2012


Ответы (7)


Попробуй это:

uniq -c | sed -r 's/^( *[^ ]+) +/\1\t/'
person Michał Kosmulski    schedule 26.07.2012
comment
Это я хотел! Спасибо всем, ребята. Я забыл, что могу наконец потерять /g. - person MoreFreeze; 27.07.2012

Пытаться:

uniq -c text.file | sed -e 's/ *//' -e 's/ /\t/'

Это удалит пробелы до количества строк, а затем заменит только первый пробел табуляцией.

Чтобы заменить все пробелы вкладками, используйте tr:

uniq -c text.file | tr ' ' '\t'

Чтобы заменить все непрерывные прогоны вкладок одной вкладкой, используйте -s:

uniq -c text.file | tr -s ' ' '\t'
person William Pursell    schedule 26.07.2012

Вы можете суммировать все числа, используя awk:

awk '{s+=$1}END{print s}'
person Igor Chubin    schedule 26.07.2012

Одним из возможных решений получения вкладок после подсчета является написание скрипта, похожего на uniq -c, который форматирует именно так, как вы хотите. Вот быстрая попытка (которая, кажется, проходит мою минуту или около того тестирования):

awk '
(NR == 1) || ($0 != lastLine) {
    if (NR != 1) {
        printf("%d\t%s\n", count, lastLine);
    }
    lastLine = $0;
    count = 1;
    next;
}
{
    count++;
}
END {
    printf("%d\t%s\n", count, lastLine);
}
' yourFile.txt
person danfuzz    schedule 26.07.2012

Другое решение. Это эквивалентно более раннему решению sed, но оно использует awk как запрошено/помечено!

cat yourFile.txt \
    | uniq -c \
    | awk '{
        match($0, /^ *[^ ]* /);
        printf("%s\t%s\n", $1, substr($0, RLENGTH + 1));
      }'
person danfuzz    schedule 26.07.2012

Основываясь на ответе Уильяма Перселла, если вам нравятся Perl-совместимые регулярные выражения (PCRE), возможно, более элегантным и современным способом будет

perl -pe 's/ *(\d+) /$1\t/'

Варианты: выполнить (-e) и распечатать (-p).

person Pablo Bianchi    schedule 01.04.2020

person    schedule
comment
Косо смотрите на любое появление cat one-file; его можно заменить перенаправлением ввода/вывода. Есть даже награда UUOC. - person Jonathan Leffler; 26.07.2012
comment
Еще одна приятная особенность Unix заключается в том, что вы можете сохранить свой код чистым и хорошо структурированным, используя конвейеры. Конечно, вы можете использовать перенаправление вместо cat file, но вполне разумно делать изложение/объяснение в такой форме (и даже производственное кодирование тоже), потому что на практике это часто оказывается более сложной командой, которая начинает работу. Аргумент производительности тоже показателен; в большинстве случаев это на самом деле не имеет значения, и вам лучше оптимизировать для удобочитаемости. - person danfuzz; 26.07.2012
comment
Да, я обычно использую его в качестве заполнителя для какого-то другого процесса, который выводит на стандартный вывод, когда привожу такие онлайн-примеры. - person vergenzt; 26.07.2012