Sto scrivendo unistruzione if-then-else utilizzando awk in uno script bash.
Quello che vorrei fare è identificare le linee con valori di col 1 che non corrispondono a una particolare stringa (rs o chr) e aggiungere un prefisso (chr) ai valori di col 1 per quelle linee identificate. Tutte le righe con la stringa corrispondente dovrebbero essere stampate come erano – nessuna aggiunta.
La mia riga di codice finora è:
awk "{if (! ($1 ~ /rs/ || $1 ~ /chr/)) {($1 == "chr"$1); print $0}}; else {print $0}" filename > newfilename
I continuare a ricevere messaggi di errore di sintassi con questo codice.
Posso eseguire lidentificazione e laggiunta con successo da solo, ma ho problemi a combinarli in un unico comando.
Commenti
Risposta
Ecco il tuo codice, espanso per la visibilità:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { ($1 == "chr"$1); print $0} }; else { print $0 } " filename > newfilename
Ci sono una serie di problemi con questo che vengono in mente
- Stai utilizzando un confronto di uguaglianza invece di un compito per provare e aggiungi il
chr
prefisso - Hai messo quello che dovrebbe essere un compito tra parentesi
- Cè un
}
dopo il primo - Non dovrebbe esserci alcun punto e virgola prima della
else
parte - Ti” manca la chiusura finale
}
dopo il codice
Ecco una versione fissa, ancora espansa:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1; print $0 } else { print $0 } } " filename > newfilename
Quindi possiamo vedere una semplice ottimizzazione per spostare il print $0
ripetuto al di fuori della tua condizione:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } print $0 } " filename > newfilename
Poiché questa è fondamentalmente una semplice “condizione → modifica” che puoi effettivamente usare la struttura standard di awk
“per semplificare ulteriormente questo aspetto. Qui abbiamo due istruzioni awk
, elaborate sequenzialmente per ogni riga del file di input. La prima riga ha il prefisso "chr"
secondo necessità. Il secondo stampa ogni riga.
awk " (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } 1 " filename > newfilename
Poiché si tratta di awk
, può anche essere arrotolato in una singola riga , anche se la leggibilità soffre un po
awk "(! ($1 ~ /rs|chr/) ) { $1 = "chr" $1 } 1" filename > newfilename
Answer
Luso di questa riga sembra funziona perfettamente:
awk "!($1 ~ /rs/ || /chr/) {$1="chr"$1}1"
Commenti
-
($1 ~ /rs/ || /chr/)
corrisponderà a$1
per"rs"
, ma$0
per"chr"
. Dovresti($1 ~ /rs/ || $1 ~ /chr/)
o($1 ~ /rs|chr/)
'{ if ( this is given) { do this } else { do that } }'