Blocco condizionale vs istruzione condizionale (if)

Supponiamo che io abbia un file:

PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17 

Voglio che ogni riga che ha un numero diverso da 1 nella seconda colonna lo cambi in 0 e mantenga il resto.

Se uso if (es. istruzione condizionale), è tutto OK:

awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0 

Ma quando utilizzo il blocco condizionale, accade qualcosa di indesiderato:

awk "$2!=1 {print $1,"0"} {print $0}" file PRO 1 GLN 0 GLN 5.55112e-17 ILE 0 ILE -6.245e-17 THR 0 THR 5.55112e-17 

Puoi vedere cosa cè che non va.

  • Come posso correggere questo errore?
  • Perché si verifica questo errore?
  • Qual è la differenza tra unistruzione condizionale e un blocco condizionale?

Risposta

In un if, hai un else. Se if non “corrisponde, viene eseguito il ramo else.

In unistruzione condizionale, entrambe le azioni sono eseguito, indipendentemente dalla condizione sia vera o falsa.

Una semplice soluzione:

$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0 

E puoi renderlo più conciso:

$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0 

Quando la condizione è vera 1 e non viene eseguita alcuna azione, awk il comportamento predefinito è print. print senza argomenti stamperà $0 per impostazione predefinita.

Commenti

  • Puoi anche giocare a golf in awk '$2!=1?$2=0:"";1' file.
  • @ terdon: Buon golf. Penso che possa essere difficile da OP capirlo.
  • @cuonglm potresti spiegare il ruolo di next. Immagino che sopprime la seconda stampa se la prima è vera. Qualcosa come continue in C.
  • @Alexander Cska: next sopprime lelaborazione della riga di input corrente, passa a quella successiva. Lo stesso ruolo di while, ma per lintero programma awk. Inoltre, awk ha la propria while

Risposta

Il secondo blocco in

awk "$2!=1 {print $1,"0"} {print $0}" file 

non è “t condizionale. Viene applicato per ogni riga e quindi stampa ogni riga.

Invece, scrivi:

awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file 

Oppure scrivi:

awk "$2!=1 {print $1,"0"; next} {print $0}" file 

Ciò farà saltare il blocco incondizionato, se il blocco condizionale viene trovato.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *