awk if-then-else error error

Scriu o declarație if-then-else folosind awk într-un script bash.

Ce aș vrea să fac este să identificăm liniile cu valori col 1 care nu se potrivesc cu un anumit șir (rs sau chr) și să adăugăm un prefix (chr) la valorile col 1 pentru acele linii identificate. Toate liniile cu șirul potrivit ar trebui să se tipărească așa cum erau – nu se adaugă.

Linia mea de cod până acum este:

awk "{if (! ($1 ~ /rs/ || $1 ~ /chr/)) {($1 == "chr"$1); print $0}}; else {print $0}" filename > newfilename 

I Continuați să primiți mesaje de eroare de sintaxă cu acest cod.

Pot efectua singuri identificarea și adăugarea cu succes, dar am probleme la combinarea acestora într-o singură comandă.

Comentarii

  • verificați unde închideți cea de-a doua paranteză: '{ if ( this is given) { do this } else { do that } }'

Răspundeți

Iată codul dvs., extins pentru vizibilitate:

awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { ($1 == "chr"$1); print $0} }; else { print $0 } " filename > newfilename 

Există o serie de probleme cu care ne amintim

  1. Folosiți o comparație de egalitate în loc de atribuire pentru a încerca și adăugați prefixul chr
  2. Ați pus ceea ce ar trebui să fie o atribuire între paranteze
  3. Există un după primul
  4. Nu ar trebui să existe punct și virgulă înainte de partea else
  5. Vă lipsește închiderea finală } după cod

Iată o versiune fixă, încă extinsă:

awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1; print $0 } else { print $0 } } " filename > newfilename 

Și apoi putem vedea o simplă optimizare pentru a muta print $0 repetată în afara stării dvs.:

awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } print $0 } " filename > newfilename 

Deoarece aceasta este în esență o simplă „condiție → modificare” pe care o puteți utiliza de fapt structura standard awk pentru a simplifica acest lucru în continuare. Aici avem două instrucțiuni awk, procesate secvențial pentru fiecare linie a fișierului dvs. de intrare. Primele linii prefixează "chr" după cum este necesar. Al doilea tipărește fiecare linie.

awk " (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } 1 " filename > newfilename 

Deoarece acesta este awk poate fi chiar înfășurat într-o singură linie , deși lizibilitatea suferă puțin

awk "(! ($1 ~ /rs|chr/) ) { $1 = "chr" $1 } 1" filename > newfilename 

Răspuns

Utilizarea acestei linii pare să funcționează perfect:

awk "!($1 ~ /rs/ || /chr/) {$1="chr"$1}1" 

Comentarii

  • ($1 ~ /rs/ || /chr/) se va potrivi cu $1 pentru "rs", dar $0 pentru "chr". Ar trebui să fie ($1 ~ /rs/ || $1 ~ /chr/) sau ($1 ~ /rs|chr/)

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *