it-roy-ru.com

Как посчитать количество уникальных значений поля в текстовом файле с разделителями табуляции?

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

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

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

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

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

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

33
sfactor

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

cat input_file | cut -f 1 | sort | uniq

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

Как избежать UUOC :)

cut -f 1 input_file | sort | uniq

Правка:

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

cut -f 1 input_file | sort | uniq | wc -l
69
codaddict

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

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

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

8
Jon Freedman
cat test.csv | awk '{ a[$1]++ } END { for (n in a) print n, a[n] } '
7
Mike

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

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

Где будет 4 доллара:

  • 1 доллар - красный 
  • 2 доллара - мяч 
  • $ 3 - 1 
  • 4 доллара - продано
2
Douglas Leeder
# COLUMN is integer column number
# INPUT_FILE is input file name

cut -f ${COLUMN} < ${INPUT_FILE} | sort -u | wc -l
2
stacker

Вот скрипт 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
0
peak

Этот скрипт выводит количество уникальных значений в каждом столбце данного файла. Предполагается, что первая строка данного файла является строкой заголовка. Нет необходимости определять количество полей. Просто сохраните сценарий в файле 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
Amin.A