erro de instrução awk if-then-else

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

  • verifique onde você fecha a segunda chave: '{ if ( this is given) { do this } else { do that } }'

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

  1. Você está usando uma comparação de igualdade em vez de atribuição para tentar e adicione o chr prefixo
  2. Você colocou o que deveria ser uma atribuição entre colchetes
  3. Há um estranho } após o primeiro
  4. Não deve haver ponto-e-vírgula antes da else parte
  5. 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/)

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *