Как посчитать количество уникальных значений поля в текстовом файле с разделителями табуляции? - PullRequest
33 голосов
/ 17 августа 2010

У меня есть текстовый файл с большим количеством данных, разделенных табуляцией.Я хочу посмотреть на данные так, чтобы я мог видеть уникальные значения в столбце.Например,

Red     Ball 1 Sold
Blue    Bat  5 OnSale
............... 

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

Мне нужно сделать это в командной строке Linux, поэтому, вероятно, с использованием некоторого bash-скрипта, sed, awk или чего-то еще.

Добавление: Спасибо всем за помощь, могу ли я попроситьеще кое-что?Что, если я хотел бы также подсчитать эти уникальные значения?

Я полагаю, что недостаточно четко изложил вторую часть.То, что я хотел сделать, это иметь счетчик «каждого» из этих уникальных значений, не зная, сколько существует уникальных значений.Например, в первом столбце я хочу узнать, сколько существует красных, синих, зеленых и т. Д. Цветных объектов.

Ответы [ 7 ]

70 голосов
/ 17 августа 2010

Вы можете использовать команды cut, sort и uniq следующим образом:

cat input_file | cut -f 1 | sort | uniq

получает уникальные значения в поле 1, замена 1 на 2 даст вам уникальные значения в поле 2.

Избежание UUOC :)

cut -f 1 input_file | sort | uniq

EDIT:

Для подсчета количества уникальных событий вы можете использовать команду wc в цепочке как:

cut -f 1 input_file | sort | uniq | wc -l
8 голосов
/ 17 августа 2010

Вы можете использовать awk, sort & uniq для этого, например, чтобы вывести список всех уникальных значений в первом столбце

awk < test.txt '{print $1}' | sort | uniq

Как написано в другом месте, если вы хотите посчитать количество экземпляров чего-либо, вы можете передать уникальный список в wc -l

7 голосов
/ 07 марта 2014
cat test.csv | awk '{ a[$1]++ } END { for (n in a) print n, a[n] } '
2 голосов
/ 17 августа 2010
# COLUMN is integer column number
# INPUT_FILE is input file name

cut -f ${COLUMN} < ${INPUT_FILE} | sort -u | wc -l
2 голосов
/ 17 августа 2010

Предполагается, что файл данных фактически разделен табуляцией и не выровнен по пробелам:

<test.tsv awk '{print $4}' | sort | uniq

Где $ 4 будет:

  • $ 1 - Красный
  • $ 2 -Мяч
  • $ 3 - 1
  • $ 4 - Продано
0 голосов
/ 26 августа 2016

Этот скрипт выводит количество уникальных значений в каждом столбце данного файла.Предполагается, что первая строка данного файла является строкой заголовка.Нет необходимости определять количество полей.Просто сохраните сценарий в файле bash (.sh) и укажите файл с разделителями табуляции в качестве параметра для этого сценария.

Код

#!/bin/bash

awk '
(NR==1){
    for(fi=1; fi<=NF; fi++)
        fname[fi]=$fi;
} 
(NR!=1){
    for(fi=1; fi<=NF; fi++) 
        arr[fname[fi]][$fi]++;
} 
END{
    for(fi=1; fi<=NF; fi++){
        out=fname[fi];
        for (item in arr[fname[fi]])
            out=out"\t"item"_"arr[fname[fi]][item];
        print(out);
    }
}
' $1

Пример выполнения:

bash> ./script.sh <path to tab-delimited file>

Пример вывода

isRef    A_15      C_42     G_24     T_18
isCar    YEA_10    NO_40    NA_50
isTv     FALSE_33  TRUE_66
0 голосов
/ 03 сентября 2015

Вот скрипт bash, который полностью отвечает на (исправленный) оригинальный вопрос.То есть, для любого файла .tsv он предоставляет синопсис для каждого из столбцов по очереди.Помимо самого bash он использует только стандартные инструменты * ix / Mac: sed tr wc cut sort uniq.

#!/bin/bash
# Syntax: $0 filename   
# The input is assumed to be a .tsv file

FILE="$1"

cols=$(sed -n 1p $FILE | tr -cd '\t' | wc -c)
cols=$((cols + 2 ))
i=0
for ((i=1; i < $cols; i++))
do
  echo Column $i ::
  cut -f $i < "$FILE" | sort | uniq -c
  echo
done
...