Resolví mi problema de RPM que no responde con:
cd /var/lib
mv rpm rpm.orig
mkdir rpm
restorecon -Rv rpm
rpm --rebuilddb
Referencias:
Un simple script awk podría hacerlo:
BEGIN {
values["A"]=1
values["T"]=2
values["C"]=3
values["G"]=4
}
{
split($0, letters, "");
sum=0;
for (letter in letters)
sum += values[letters[letter]];
print "seq_number", NR, "has score =", sum;
}
Cuando se ejecuta en sus datos de muestra, obtengo:
$ awk -f score.awk < input
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
bueno, dado que esta pregunta se responde de todos modos, aquí hay algunas perl/ruby
una -líneas
$ perl -MList::Util=sum0 -lne 'print "seq_number $. has score = ", sum0 split //, tr/ATCG/1234/r' ip.txt
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
$ ruby -ne 'puts "seq_number #{$.} has score = #{$_.tr("ATCG", "1234").chars.sum(&:to_i)}"' ip.txt
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
La idea es la misma y aplicable siempre que las letras se traduzcan en números de un solo dígito
tr
para cambiar ATCG
al correspondiente1234
Y una versión awk
que usa el valor de retorno desplit
$ awk 'BEGIN{a["A"]=1; a["T"]=2; a["C"]=3; a["G"]=4}
{score = 0; for(k in a) score += (split($0, n, k)-1)*a[k];
print "seq_number " NR " has score = " score}' ip.txt
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
sed -e 's/A/./g' -e 's/T/../g' \
-e 's/C/.../g' -e 's/G/..../g' file |
awk '{ printf("seq_number %d has score = %d\n", NR, length) }'
Salida:
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
El comando sed
reemplaza cada base por un número de puntos que representan la puntuación. El comando awk
imprime el número de líneas leídas hasta el momento y también calcula la longitud de la línea, que es la puntuación total de esa línea.
La primera expresión sed
, s/A/./g
, en realidad no es necesaria para que el resultado sea correcto.
Variación (un poco más corta, solo por diversión):
sed -e 's/G/TT/g;s/C/TA/g;s/T/AA/g' file |
awk '{ printf("seq_number %d has score = %d\n", NR, length) }'
Variación que da solo las puntuaciones, una por línea:
tr 'ATCG' '1234' <file | awk -F'\0' -vOFS="+" '$1=$1' | bc
Esto primero reemplaza cada letra con el dígito que es el puntaje para esa letra, y luego, con awk
, inserta +
entre cada dígito. bc
maneja el cálculo de la puntuación total de cada línea.
Y finalmente, una variación del último pero con solo sed
ybc
(nuevamente, solo se imprimen las partituras):
sed 'y/ATCG/1234/;s/\(.\)/+\1/g;s/^+//' file | bc
A Sundeep se le ocurrió
sed 'y/ATCG/1234/;s/./+&/2g' file | bc
que es una variación más breve de lo último.
Primero cambia las letras a los dígitos correspondientes con el comando y
, y luego reemplaza cada carácter (a partir del segundo )precedido por +
, así que para la cadena de entrada ACCA
obtendrá 1+3+3+1
como salida. bc
se utiliza entonces para evaluar esta expresión aritmética.
Su solución solo funciona en GNU sed
como estándar sed
no le gusta tener ambos 2
y g
como banderas de sustitución al mismo tiempo.