Как я могу посчитать вхождения строки в файле, используя bash? (с плюсом) - PullRequest
0 голосов
/ 13 марта 2020

Это будет вход :

a b 125
a b 358
d t 485
d f 859
d t 789
a t 154

Это будет выход :

2 a b 125
2 d t 485
1 d f 859
1 a t 154

Важно : обратите внимание, что мне нужно сделать следующее:

1 - подсчитать вхождения первых двух столбцов, объединенных. Например:

a b 125
a b 358

Это будет 2 вхождения последовательности ab .

2 - сохранить первое вхождение id (3-й столбец) для каждой последовательности , Например:

a b 125
a b 358

В этом случае я хотел бы вывести 2 ab 125 .

Ответы [ 3 ]

3 голосов
/ 13 марта 2020

Это решение работает для описанного теста:

sort -t' ' -k1,2 file | uniq -cw4 | sort -r
1 голос
/ 13 марта 2020

Если ключи в столбцах 1 и 2 имеют переменную длину, то я думаю, что awk является инструментом выбора. Это похоже на ответ David C. Rankin , но он был разработан независимо.

awk '{ if (count[$1, $2]++ == 0) { line[$1, $2] = $0; order[n++] = $1 SUBSEP $2 } }
     END { for (i = 0; i < n; i++) printf "%d %s\n", count[order[i]], line[order[i]] }'

Первая строка увеличивает счет для записи со столбцами 1 и 2; если это было 0 (до приращения), тогда захватите строку (проиндексированную столбцами 1 и 2) и захватите ключ (столбцы 1 и 2, разделенные SUBSEP) в order[n++].

В конце обработайте ключи в order, индексируя соответствующие данные в count и line.

Для ваших входных данных это выдает:

2 a b 125
2 d t 485
1 d f 859
1 a t 154

Но это также работает правильно, если ключи имеют переменную длину. Существует множество возможных уточнений, таких как определение длины самого большого счетчика, чтобы счетчики были выровнены по правому краю, и если вы имеете дело с ключами переменной длины, вы можете отследить, какой из ключей самый длинный в столбце 1 и столбце 2, чтобы вы могли выровнять ключи тоже.

1 голос
/ 13 марта 2020

Если вам необходимо сохранить желаемый порядок вывода, вы можете использовать awk и 3-массивы для хранения количества раз, которое видны первые два поля (массив a), массив, который сохраняет порядок встречаются первые два поля (массив b) и, наконец, массив, который отображает первые два поля с первым видимым третьего поля (массив c):

awk -v n=1 '{ a[$1" "$2]++ }
    $1" "$2 in c {next}
    {   b[n++]=$1" "$2; 
        c[$1" "$2]=$3
    }
    END { for (i in b) print a[b[i]], b[i], c[b[i]] }
' file

выше $1" "$2 - это объединение первых двух полей, используемых в качестве общего индекса для массивов a и c и используемых в качестве значения в массиве b, которое сохраняет порядок.

Пример Использование / Выходные данные

Имея входной файл в file, вы можете просто скопировать и вставить средней кнопкой мыши сценарий выше в xterm в каталоге, содержащем file, и ваш результат будет в указанном вами порядке :

$ awk -v n=1 '{ a[$1" "$2]++ }
>     $1" "$2 in c {next}
>     {   b[n++]=$1" "$2;
>         c[$1" "$2]=$3
>     }
>     END { for (i in b) print a[b[i]], b[i], c[b[i]] }
> ' file
2 a b 125
2 d t 485
1 d f 859
1 a t 154

Использование SUBSEP

Как указано @JonathanLeffler в комментариях ниже, вы также можете указать индексирование как a[$1,$2], используемое для представления многомерных массивов. где символ ',' заменяется встроенной переменной SUBSEP, равной "\034". Для этого также требуются корректировки во втором тесте правила и значение для массива b. С корректировками вы получите:

awk -v n=1 '{ a[$1,$2]++ } 
    $1 SUBSEP $2 in c { next }
    {
        b[n++]=$1 SUBSEP $2
        c[$1,$2]=$3
    }
    END {for (i in b) print a[b[i]], b[i], c[b[i]]}
' file

Здесь будет работать либо конкатенация, либо разделение с SUBSEP, но для формального моделирования многомерного массива следует использовать SUBSEP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...