Estoy escribiendo una declaración if-then-else usando awk en un script bash.
Lo que me gustaría hacer es identificar líneas con valores de columna 1 que no coincidan con una cadena en particular (rs o chr) y agregar un prefijo (chr) a los valores de columna 1 para esas líneas identificadas. Todas las líneas con la cadena coincidente deben imprimirse como estaban, sin agregar.
Mi línea de código hasta ahora es:
awk "{if (! ($1 ~ /rs/ || $1 ~ /chr/)) {($1 == "chr"$1); print $0}}; else {print $0}" filename > newfilename
I sigo recibiendo mensajes de error de sintaxis con este código.
Puedo realizar la identificación y la adición con éxito por su cuenta, pero tengo problemas para combinarlos en un solo comando.
Comentarios
Respuesta
Aquí está su código, ampliado para mayor visibilidad:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { ($1 == "chr"$1); print $0} }; else { print $0 } " filename > newfilename
Hay una serie de problemas con esto que me vienen a la mente
- Estás usando una comparación de igualdad en lugar de una asignación para probar y agregue el prefijo
chr
- Ha puesto lo que debería ser una asignación entre corchetes
- Hay un
}
después del primer - No debe haber punto y coma antes de la
else
parte - Te falta el cierre final
}
después del código
Aquí hay una versión fija, aún expandida:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1; print $0 } else { print $0 } } " filename > newfilename
Y luego podemos ver una optimización simple para mover el print $0
repetido fuera de su condición:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } print $0 } " filename > newfilename
Dado que Esto es básicamente una simple «condición → enmendar». De hecho, puede usar la estructura estándar de awk
«para simplificar esto aún más. Aquí tenemos dos awk
declaraciones, procesadas secuencialmente para cada línea de su archivo de entrada. La primera línea tiene el prefijo "chr"
según sea necesario. El segundo imprime cada línea.
awk " (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } 1 " filename > newfilename
Como es awk
, incluso se puede enrollar en una sola línea , aunque la legibilidad sufre un poco
awk "(! ($1 ~ /rs|chr/) ) { $1 = "chr" $1 } 1" filename > newfilename
Respuesta
El uso de esta línea parece funciona perfectamente:
awk "!($1 ~ /rs/ || /chr/) {$1="chr"$1}1"
Comentarios
-
($1 ~ /rs/ || /chr/)
coincidirá con$1
para"rs"
, pero$0
para"chr"
. Debes($1 ~ /rs/ || $1 ~ /chr/)
o($1 ~ /rs|chr/)
'{ if ( this is given) { do this } else { do that } }'