awk if-then-else-sætningsfejl

Jeg skriver en if-then-else-sætning ved hjælp af awk i et bash-script.

Hvad jeg gerne vil gøre er at identificere linjer med col 1-værdier, der ikke matcher en bestemt streng (rs eller chr) og tilføje et præfiks (chr) til col 1-værdierne for de identificerede linjer. Alle linjer med den matchede streng skal udskrives som de var – ingen tilføjelse.

Min kodelinje hidtil er:

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

I fortsæt med at modtage syntaksfejlmeddelelser med denne kode.

Jeg kan udføre identifikationen og tilføjelsen med succes alene, men har problemer med at kombinere dem i en kommando.

Kommentarer

  • tjek, hvor du lukker den anden krøllede parentes: '{ if ( this is given) { do this } else { do that } }'

Svar

Her er din kode, udvidet til synlighed:

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

Der er en række problemer med dette, der kommer i tankerne

  1. Du bruger en ligestillingssammenligning i stedet for opgave for at prøve og tilføj chr præfikset
  2. Du har sat hvad der skal være en opgave i parentes
  3. Der er en ekstern } efter den første
  4. Der bør ikke være noget semikolon før else del
  5. Du mangler den sidste lukning } efter koden

Her er en fast version, stadig udvidet:

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

Og så kan vi se en simpel optimering for at flytte den gentagne print $0 uden for din tilstand:

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

Siden dette er grundlæggende en simpel “betingelse → ændring”, du kan faktisk bruge awk “s standardstruktur til at forenkle dette yderligere. Her har vi to awk udsagn, behandlet sekventielt for hver linje i din inputfil. Første liniepræfikser "chr" efter behov. Den anden udskriver hver linje.

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

Da dette er awk, kan den endda rulles op til en enkelt linje , selvom læsbarheden lider lidt

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

Svar

Brug af denne linje ser ud til at fungerer perfekt:

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

Kommentarer

  • ($1 ~ /rs/ || /chr/) vil matche $1 for "rs", men $0 til "chr". Du skal enten ($1 ~ /rs/ || $1 ~ /chr/) eller ($1 ~ /rs|chr/)

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *