linux - veces - ¿Cómo contar el número de valores únicos de un campo en un archivo de texto delimitado por tabulaciones?
contar.si.conjunto valores unicos (7)
Tengo un archivo de texto con una gran cantidad de datos delimitados por tabuladores. Quiero echar un vistazo a los datos para poder ver los valores únicos en una columna. Por ejemplo,
Red Ball 1 Sold
Blue Bat 5 OnSale
...............
Por lo tanto, es como que la primera columna tiene colores, por lo que quiero saber cuántos valores únicos diferentes hay en esa columna y quiero poder hacer eso para cada columna.
Necesito hacer esto en una línea de comandos de Linux, así que probablemente use algunos script bash, sed, awk o algo así.
Adición: Gracias a todos por la ayuda, ¿puedo preguntar una cosa más? ¿Y si también quisiera contar estos valores únicos?
Supongo que no puse la segunda parte lo suficientemente clara. Lo que quería hacer es tener un recuento de "cada uno" de estos valores únicos, sin saber cuántos valores únicos hay. Por ejemplo, en la primera columna quiero saber cuántos objetos de colores rojos, azules, verdes, etc. hay allí.
Aquí hay un script bash que responde completamente la pregunta original (revisada). Es decir, dado cualquier archivo .tsv, proporciona la sinopsis para cada una de las columnas sucesivamente. Además de bash, solo utiliza herramientas estándar * 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
Este script genera el número de valores únicos en cada columna de un archivo determinado. Asume que la primera línea del archivo dado es la línea del encabezado. No hay necesidad de definir el número de campos. Simplemente guarde el script en un archivo bash (.sh) y proporcione el archivo delimitado por tabulaciones como un parámetro para este script.
Código
#!/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
Ejemplo de ejecución:
bash> ./script.sh <path to tab-delimited file>
Ejemplo de salida
isRef A_15 C_42 G_24 T_18
isCar YEA_10 NO_40 NA_50
isTv FALSE_33 TRUE_66
Puede usar awk, sort & uniq para hacer esto, por ejemplo, para listar todos los valores únicos en la primera columna
awk < test.txt ''{print $1}'' | sort | uniq
Como se publicó en otra parte, si desea contar el número de instancias de algo, puede canalizar la lista única en wc -l
Puede utilizar los comandos de cut
, sort
y uniq
siguiente manera:
cat input_file | cut -f 1 | sort | uniq
obtiene valores únicos en el campo 1, reemplazando 1 por 2 le dará valores únicos en el campo 2.
Evitando UUOC :)
cut -f 1 input_file | sort | uniq
EDITAR:
Para contar el número de ocurrencias únicas, puede hacer uso del comando wc
en la cadena como:
cut -f 1 input_file | sort | uniq | wc -l
Suponiendo que el archivo de datos en realidad está separado por tabuladores, no alineado por espacios:
<test.tsv awk ''{print $4}'' | sort | uniq
Donde $ 4 será:
- $ 1 - Rojo
- $ 2 - Bola
- $ 3 - 1
- $ 4 - Vendido
# COLUMN is integer column number
# INPUT_FILE is input file name
cut -f ${COLUMN} < ${INPUT_FILE} | sort -u | wc -l
cat test.csv | awk ''{ a[$1]++ } END { for (n in a) print n, a[n] } ''