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
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.
awk '$2!=1?$2=0:"";1' file
.next
. Immagino che sopprime la seconda stampa se la prima è vera. Qualcosa comecontinue
inC
.next
sopprime lelaborazione della riga di input corrente, passa a quella successiva. Lo stesso ruolo diwhile
, ma per lintero programmaawk
. Inoltre,awk
ha la propriawhile