sintaxis - perl stdin
¿Cuenta el número de términos coincidentes en un archivo de texto? (5)
Podrías hacer esto, que probablemente es a lo que te dirigías. Básicamente cuenta el número de coincidencias usando "wc -l" y luego, si es mayor que cero, genera la cadena de búsqueda y el número de coincidencias:
#!/bin/bash
while read line
do
line=${line##+ } # Strip off leading + and space
n=$(grep "$line" data.txt 2> /dev/null | wc -l)
if [ $n -gt 0 ]; then
echo $line $n
fi
done < input_list.txt
Estoy tratando de contar el número de términos coincidentes de una lista de entrada que contiene un término por línea con un archivo de datos y crear un archivo de salida que contiene el término emparejado (grep''d) con el número de coincidencias.
El input_list.txt se ve así:
+ 5S_rRNA
+ 7SK
+ AADAC
+ AC000111.3
+ AC000111.6
El archivo data.txt:
chr10 101780038 101780209 5S_rRNA
chr10 103578280 103578430 5S_rRNA
chr10 112327234 112327297 5S_rRNA
chr10 120766459 120766601 7SK
chr10 127408228 127408317 7SK
chr10 127511874 127512063 AADAC
chr10 14614140 14614294 AC000111.3
chr10 14695964 14696146 AC000111.6
Me gustaría crear un archivo de salida (output.txt) que contenga los términos coincidentes con su recuento correspondiente.
+ 5S_rRNA 3
+ 7SK 2
+ AADAC 1
+ AC000111.3 1
+ AC000111.6 1
Hasta ahora, he producido una lista que contiene todos los términos coincidentes utilizando el siguiente script, pero todos los intentos de proporcionar un recuento de los términos coincidentes no han funcionado.
exec < input_list.txt
while read line
do
grep -w data.txt | awk ''{print $0}''| sort| uniq >> grep_output.txt
done
He intentado grep -o -w | wc -l and grep -w data.txt | wc -l
grep -o -w | wc -l and grep -w data.txt | wc -l
grep -o -w | wc -l and grep -w data.txt | wc -l
etc., pero no puedo encontrar la forma de generar una lista de salida que contenga el término coincidente con su conteo correspondiente.
¡Cualquier sugerencia seria genial!
Puedes grep las palabras de la entrada.txt y usar uniq para obtener los conteos:
cut -d'' '' -f2 input.txt | grep -o -f - data.txt | sort | uniq -c
Da:
3 5S_rRNA
2 7SK
1 AADAC
1 AC000111.3
1 AC000111.6
También puede agregar otro sed para obtener salida formateada:
cut -d'' '' -f2 input.txt | grep -o -f - data.txt | sort | uniq -c | /
sed ''s//s*/([0-9]*/)/s*/(.*/)/+ /2/t/1/''
Produce:
+ 5S_rRNA 3
+ 7SK 2
+ AADAC 1
+ AC000111.3 1
+ AC000111.6 1
Puedes hacer esto en perl usando hashes también:
#!/usr/bin/perl
use warnings;
use strict;
open my $list, ''<'', ''in.txt'' or die "$!";
open my $input, ''<'', ''in.2.txt'' or die "$!";
my @split;
my (%data, %hash, %exists);
while(<$input>){
chomp;
@split = split(//s+/);
my ($info) = $split[3];
$data{$info}++;
}
while (<$list>){
chomp;
my @split = split(//+ /);
my ($match) = $split[1];
$hash{$match} = 1;
}
my $count = 0;
for my $compare (keys %hash){
if (exists $data{$compare} ){
$exists{$compare} = $data{$compare};
}
}
foreach my $c (keys %exists){
print "+ $c: $exists{$c}/n"
}
Salida:
+ 5S_rRNA: 3
+ AADAC: 1
+ 7SK: 2
+ AC000111.6: 1
+ AC000111.3: 1
awk
puede ser bueno para esto:
$ awk ''NR==FNR {vals[$2]=$2}
$4 in vals {count[$4]++}
END {for (i in count) print i, count[i]}'' input_list data.txt
AC000111.3 1
AC000111.6 1
5S_rRNA 3
AADAC 1
7SK 2
Explicación
vals[]
almacena el segundo campo del archivo input_list
. Luego, verifica si el 4to campo del segundo archivo data.txt
está en cualquier línea y cuenta las ocurrencias en la matriz count[]
. Finalmente imprime la salida en el bloque END{}
.
Tubería para sort
con n
(numérico) r
(reverso) y k2
(2da columna) opciones, obtiene datos ordenados:
$ awk ''NR==FNR {vals[$2]=$2}
$4 in vals {count[$4]++}
END {for (i in count) print i, count[i]}'' input_list data.txt | sort -rnk2
5S_rRNA 3
7SK 2
AC000111.6 1
AC000111.3 1
AADAC 1
perl -lane ''$s{ $F[3] }++ END{ print "+ $_ $s{$_}" for sort keys %s }'' data.txt