web-dev-qa-db-ja.com

タブ区切りテキストファイルのフィールドの一意の値の数をカウントする方法は?

タブ区切りの大量のデータを含むテキストファイルがあります。列の一意の値を確認できるように、データを確認したいと思います。例えば、

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

そのため、最初の列のように色があるので、その列にいくつの異なる一意の値があるかを知りたいので、各列でそれを実行できるようにします。

Linuxコマンドラインでこれを行う必要があるので、おそらくbashスクリプト、sed、awkなどを使用します。

補遺:助けてくれてありがとう、もう1つ質問できますか?これらの一意の値のカウントが必要な場合はどうなりますか?

2番目の部分を十分に明確に記述しなかったと思います。私がしたいのは、これらの一意の値の「それぞれ」の数に、一意の値の数がわからないようにすることです。列赤、青、緑などの色付きオブジェクトがいくつあるかを知りたい

34
sfactor

次のように、cutsort、および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
72
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] } '
8
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