If you want all transcripts from that gtf file whose type isn't "protein_coding", you can use almost the same command, just change the ==
("is") to !=
("isn't"):
awk '{if($3=="transcript" && $20!="\"protein_coding\";"){print $0}}' gencode.gtf
Or, a simpler version:
awk '$3=="transcript" && $20!="\"protein_coding\";"' gencode.gtf
Note that this will not include any of the havana transcripts in the file, but I am assuming that's what you want since that's what your original command did.
Specifically, the command will return the following types of transcript (the numbers on the left are the number of such transcripts in the file):
awk '$3=="transcript" && $20!="\"protein_coding\";"{print $20}' gencode.gtf | sort | uniq -c | sort -nk1
1 "translated_processed_pseudogene";
2 "Mt_rRNA";
3 "IG_J_pseudogene";
3 "TR_D_gene";
4 "TR_J_pseudogene";
5 "TR_C_gene";
10 "IG_C_pseudogene";
18 "IG_C_gene";
18 "IG_J_gene";
22 "Mt_tRNA";
25 "3prime_overlapping_ncrna";
27 "TR_V_pseudogene";
37 "IG_D_gene";
58 "non_stop_decay";
59 "polymorphic_pseudogene";
74 "TR_J_gene";
97 "TR_V_gene";
144 "IG_V_gene";
182 "unitary_pseudogene";
196 "IG_V_pseudogene";
330 "sense_overlapping";
387 "pseudogene";
442 "transcribed_processed_pseudogene";
531 "rRNA";
802 "sense_intronic";
860 "transcribed_unprocessed_pseudogene";
1529 "snoRNA";
1923 "snRNA";
2050 "misc_RNA";
2549 "unprocessed_pseudogene";
3116 "miRNA";
9710 "antisense";
10623 "processed_pseudogene";
11780 "lincRNA";
13052 "nonsense_mediated_decay";
25955 "retained_intron";
28082 "processed_transcript";
You might also want to remove that "translated_processed_pseudogene" since that is actually translated into protein and is therefore technically coding:
awk '$3=="transcript" &&
$20!="\"protein_coding\";" &&
$20!="\"translated_processed_pseudogene\";"' gencode.gtf