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
chrprefisso - Hai messo quello che dovrebbe essere un compito tra parentesi
- Cè un
}dopo il primo - Non dovrebbe esserci alcun punto e virgola prima della
elseparte - 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$1per"rs", ma$0per"chr". Dovresti($1 ~ /rs/ || $1 ~ /chr/)o($1 ~ /rs|chr/)
'{ if ( this is given) { do this } else { do that } }'