简体   繁体   中英

Using an if/else statement in the middle of AWK

I have a 5-column file:

PS 6 15 0 1
PS 1 17 0 1
PS 4 18 0 1

that I would like to get it in this 7-column format:

PS.15 PS 6 N 1 0 1
PS.17 PS 1 P 1 0 1
PS.18 PS 4 N 1 0 1

To create 6 of the 7 columns requires just grabbing directly (and sometimes applying small arithmetic) from columns in the original file. However, to create one column (column 4) requires an if-else statement.

Specifically, to create new columns 1, 2, 3, I use:

 cat File | awk '{print $1"."$3"\t"$1"\t"$2}'

and to create new columns 5, 6,7, I use:

 cat testFileB | awk '{print $4+$5"\t"$4/($4+$5)"\t"$5/($4+$5)}'

and to create new column 4, I use:

 cat testFileB | awk '{if ($2 == 1 || $2 == 2 || $2 == 3) print "P"; else print "N";}'

These three statements work fine independently and get me what I want (the correct values for the columns that are all separated by tabs). However, when I try to apply them simultaneously (create all 7 columns at once), I can only do so with unwanted new lines (instead of tabs) before and after column 4 (the if/else statement column):

For instance, my attempt to simultaneously create columns 1, 2, 3, 4:

 cat File | awk '{print $1"."$3"\t"$1"\t"$2; if ($2 == 1 || $2 == 2 || $2 == 3) print "P"; else print "N";}'

results in unwanted new lines before column 4:

PS.15 PS 6
N
PS.17 PS 1
P
PS.18 PS 4

Similarly, my attempt to simultaneously create columns 4, 5, 6, 7:

 cat File | awk '{if ($2 == 1 || $2 == 2 || $2 == 3) print "P"; else print "N"; print $4+$5"\t"$4/($4+$5)"\t"$5/($4+$5)}'

results in unwanted new lines after column 4:

N
1 0 1
P
1 0 1
N
1 0 1

Is there a solution so that I can create all 7 columns at once, and there are only tabs between them (no new lines)?

If you don't want automatic line feeds, you can just use printf instead of print . I'm not quite sure if you want a tab separating the N1 or not, but that's easy enough to adjust;

cat testfile | awk '{printf "%s.%s\t%s\t%s\t",$1,$3,$1,$2; if ($2 == 1 || $2 == 2 || $2 == 3) printf "P"; else printf "N"; print $4+$5"\t"$4/($4+$5)"\t"$5/($4+$5)}'

PS.15   PS  6   N1  0   1
PS.17   PS  1   P1  0   1
PS.18   PS  4   N1  0   1

Simply set your OFS (instead of repeating a \\t all across the line), and use the ternary operator to print P or N:

$ awk -v OFS='\t' '{s=$4+$5;print $1"."$3,$1,$2,($2~/^[123]$/?"P":"N"),s,$4/s,$5/s}' file
PS.15   PS      6       N       1       0       1
PS.17   PS      1       P       1       0       1
PS.18   PS      4       N       1       0       1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM