Estou escrevendo uma instrução if-then-else usando awk em um script bash.
O que eu gostaria de fazer é identificar as linhas com os valores da coluna 1 que não correspondem a uma determinada string (rs ou chr) e acrescentar um prefixo (chr) aos valores da coluna 1 para essas linhas identificadas. Todas as linhas com a string correspondente devem ser impressas como estavam – sem acréscimos.
Minha linha de código até agora é:
awk "{if (! ($1 ~ /rs/ || $1 ~ /chr/)) {($1 == "chr"$1); print $0}}; else {print $0}" filename > newfilename
I continuo recebendo mensagens de erro de sintaxe com este código.
Posso realizar a identificação e a anexação por conta própria, mas estou tendo problemas para combiná-los em um comando.
Comentários
Resposta
Aqui está o seu código, expandido para visibilidade:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { ($1 == "chr"$1); print $0} }; else { print $0 } " filename > newfilename
Há uma série de problemas com isso que vêm à mente
- Você está usando uma comparação de igualdade em vez de atribuição para tentar e adicione o
chr
prefixo - Você colocou o que deveria ser uma atribuição entre colchetes
- Há um estranho
}
após o primeiro - Não deve haver ponto-e-vírgula antes da
else
parte - Você está perdendo o fechamento final
}
após o código
Aqui está uma versão fixa, ainda expandida:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1; print $0 } else { print $0 } } " filename > newfilename
E então podemos ver uma otimização simples para mover o print $0
repetido para fora de sua condição:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } print $0 } " filename > newfilename
Desde esta é basicamente uma simples “condição → corrigir”, você pode realmente usar a estrutura padrão de awk
“para simplificar ainda mais. Aqui, temos duas awk
instruções, processadas sequencialmente para cada linha de seu arquivo de entrada. A primeira linha prefixa "chr"
conforme necessário. O segundo imprime todas as linhas.
awk " (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } 1 " filename > newfilename
Como se trata de awk
, pode até ser enrolado em uma única linha , embora a legibilidade diminua um pouco
awk "(! ($1 ~ /rs|chr/) ) { $1 = "chr" $1 } 1" filename > newfilename
Resposta
Usar esta linha parece funcionam perfeitamente:
awk "!($1 ~ /rs/ || /chr/) {$1="chr"$1}1"
Comentários
-
($1 ~ /rs/ || /chr/)
corresponderá a$1
para"rs"
, mas$0
para"chr"
. Você deve($1 ~ /rs/ || $1 ~ /chr/)
ou($1 ~ /rs|chr/)
'{ if ( this is given) { do this } else { do that } }'