how to split data in 5 letters around one specific letter for each section - awk

I have a data like this
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RNDDDDTSVCLGTRQCSWFAGCTNRTWNSSAVPLIGLPNTQDYKWVDRNSGLTWSGNDTCLYSCQNQTKGLLYQLFRNLFCSYGLTEAHGKWRCADASITNDKGHDGHRTPTWWLTGSNLTLSVNNSGLFFLCGNGVYKGFPPKWSGRCGLGYLVPSLTRYLTLNASQITNLRSFIHKVTPHR
>sp|P13674|P4HA1_HUMAN Prolyl 4-hydroxylase subunit alpha-1 OS=Homo sapiens OX=9606 GN=P4HA1 PE=1 SV=2
VECCPNCRGTGMQIRIHQIGPGMVQQIQSVCMECQGHGERISPKDRCKSCNGRKIVREKKILEVHIDKGMKDGQKITFHGEGDQEPGLEPGDIIIVLDQKDHAVFTRRGEDLFMCMDIQLVEALCGFQKPISTLDNRTIVITSHPGQIVKHGDIKCVLNEGMPIYRRPYEKGRLIIEFKVNFPENGFLSPDKLSLLEKLLPERKEVEE
>sp|Q7Z4N8|P4HA3_HUMAN Prolyl 4-hydroxylase subunit alpha-3 OS=Homo sapiens OX=9606 GN=P4HA3 PE=1 SV=1
MTEQMTLRGTLKGHNGWVTQIATTPQFPDMILSASRDKTIIMWKLTRDETNYGIPQRALRGHSHFVSDVVISSDGQFALSGSWDGTLRLWDLTTGTTTRRFVGHTKDVLSVAFSSDNRQIVSGSRDKTIKLWNTLGVCKYTVQDESHSEWVSCVRFSPNSSNPIIVSCGWDKLVKVWNLANCKLK
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
IQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQL
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
MQPILLLLAFLLLPRADAGEIIGGHEAKPHSRPYMAYLMIWDQKSLKRCGGFLIRDDFVLTAAHCWGSSINVTLGAHNIKEQEPTQQFIPVKRPIPHPAYNPKNFSNDIMLLQLERKAKRTRAVQPLRLPSNKAQVKPGQTCSVAGWGQTAPLGKHSHTLQEVKMTVQEDRKCES
>sp|Q9UHX1|PUF60_HUMAN Poly(U)-binding-splicing factor PUF60 OS=Homo sapiens OX=9606 GN=PUF60 PE=1 SV=1
MGKDYYQTLGLARGASDEEIKRAYRRQALRYHPDKNKEPGAEEKFKEIAEAYDVLSDPRKREIFDRYGEEGLKGSGPSGGSGGGANGTSFSYTFHGDPHAMFAEFFGGRNPFDTFFGQRNGEEGMDIDDPFSGFPMGMGGFTNVNFGRSRSAQEPARKKQDPPVTHDLRVSLEEIYSGCTKKMKISHK
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
IVVKGHSTCLSEGALSPDGTVLATASHDGYVKFWQIYIEGQDEPRCLHEWKPHDGRPLSCLLFCDNHKKQDPDVPFWRFLITGADQNRELKMWCTVSWTCLQTIRFSPDIFSSVSVPPSLKVCLDLSAEYLILSDVQRKVLYVMELLQNQEEGHACFSSISEFLLTHPVLSFGIQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQLNPDVVAPLPTHTAHEDFTFGESRPELGSEGLGSAAHGSQPDLRRIVELPAPADFLSLSSETKPKLMTPDAFMTPSASLQQITASPSSSSSGSSSSSSSSSSSLTAVSAMSSTSAVDPSLTRPPEELTLSPKLQLDGSLTMSSSGSLQASPRGLLPGLLPAPADKLTPKGPGQVPTATSALSLELQEVEP
>sp|O14683|P5I11_HUMAN Tumor protein p53-inducible protein 11 OS=Homo sapiens OX=9606 GN=TP53I11 PE=1 SV=2
MIHNYMEHLERTKLHQLSGSDQLESTAHSRIRKERPISLGIFPLPAGDGLLTPDAQKGGETPGSEQWKFQELSQPRSHTSLKVSNSPEPQKAVEQEDELSDVSQGGSKATTPASTANSDVATIPTDTPLKEENEGFVKVTDAPNKSEISKHIEVQVAQETRNVSTGSAENEEKSEVQAIIESTPELDMDKDLSGYKGSSTPTKGIENKAFDRNTESLFEELSSAGSGLIGDVDEGADLLGMGREVENLILENTQLLETKNALNIVKNDLIAKVDELTCEKDVLQGELEAVKQAKLKLEEKNRELEEELRKARAEAEDARQKAKDDDDSDIPTAQRKRFTRVEMARVLMERNQYKERLMELQEAVRWTEMIRASRENPAMQEKKRSSIWQFFSRLFSSSSNTTKKPEPPVNLKYNAPTSHVTPSVK
I am trying to find 5 letter left and 5 letters right to each F for each section and then calculate the number of E or D in each of them
a representative output looks like below
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RQCSWFAGCTN 0 0
LLYQLFRNLFC 0 0
LFRNLFCSYGL 0 0
NNSGLFFLCGN 0 0
NSGLFFLCGNG 0 0
GVYKGFPPKWS 0 0
TNLRSFIHKVT 0 0
>sp|P13674|P4HA1_HUMAN Prolyl 4-hydroxylase subunit alpha-1 OS=Homo sapiens OX=9606 GN=P4HA1 PE=1 SV=2
GQKITFHGEGD 1 1
KDHAVFTRRGE 1 1
RGEDLFMCMDI 1 2
EALCGFQKPIS 1 0
RLIIEFKVNFP 1 0
EFKVNFPENGF 2 0
FPENGFLSPDK 1 0
>sp|Q7Z4N8|P4HA3_HUMAN Prolyl 4-hydroxylase subunit alpha-3 OS=Homo sapiens OX=9606 GN=P4HA3 PE=1 SV=1
ATTPQFPDMIL 0 1
RGHSHFVSDVV 0 1
SSDGQFALSGS 0 1
TTTRRFVGHTK 0 0
VLSVAFSSDNR 0 1
VSCVRFSPNSS 0 0
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
VLIKLFCVHTK 0 0
DVQIRFQPQL 0 1
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
LLLLAFLLLPR 0 0
KRCGGFLIRDD 0 2
LIRDDFVLTAA 0 2
EPTQQFIPVKR 1 0
YNPKNFSNDIM 0 1
>sp|Q9UHX1|PUF60_HUMAN Poly(U)-binding-splicing factor PUF60 OS=Homo sapiens OX=9606 GN=PUF60 PE=1 SV=1
GAEEKFKEIAE 4 0
RKREIFDRYGE 2 1
ANGTSFSYTFH 0 0
SFSYTFHGDPH 0 1
DPHAMFAEFFG 0 1
AMFAEFFGGRN 1 0
MFAEFFGGRNP 1 0
GGRNPFDTFFG 0 1
NPFDTFFGQRN 0 1
PFDTFFGQRNG 0 1
DIDDPFSGFPM 0 3
DPFSGFPMGMG 0 1
MGMGGFTNVNF 0 0
FTNVNFGRSRS 0 0
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
DGYVKFWQIYI 0 1
LSCLLFCDNHK 0 1
DPDVPFWRFLI 0 2
VPFWRFLITGA 0 0
LQTIRFSPDIF 0 1
FSPDIFSSVSV 0 1
EGHACFSSISE 0 0
SSISEFLLTHP 1 0
HPVLSFGIQVV 0 0
VLIKLFCVHTK 0 0
DVQIRFQPQLN 0 1
TAHEDFTFGES 2 1
HEDFTFGESRP 2 1
PAPADFLSLSS 0 1
MTPDAFMTPSA 0 1
>sp|O14683|P5I11_HUMAN Tumor protein p53-inducible protein 11 OS=Homo sapiens OX=9606 GN=TP53I11 PE=1 SV=2
ISLGIFPLPAG 0 0
SEQWKFQELSQ 2 0
EENEGFVKVTD 3 1
IENKAFDRNTE 2 1
NTESLFEELSS 3 0
AQRKRFTRVEM 1 0
SSIWQFFSRLF 0 0
SIWQFFSRLFS 0 0
FFSRLFSSSSN 0 0
at the begging I thought of finding the 5 letters left and right to F.
but I could not figure it out how to do that

In awk:
$ awk '
NR%2 {print; next } # print every odd record
{ # the even records are processed
while(match($0,/.{5}F.{0,5}/)) { # get 5 before and upto 5 after F
# 5 before F ^^^ ^^^ 0-5 chars after F
# change to /.{0,5}F.{0,5}/ if needed
print s=substr($0,RSTART,RLENGTH), # print match
gsub(/E/,"E",s), # count of Es
gsub(/D/,"D",s) # count of Ds
$0=substr($0,RSTART+1) # shorten the search string
}
}' file
Some output:
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RQCSWFAGCTN 0 0
LLYQLFRNLFC 0 0 # notice another F in the 5+F+5 window
LFRNLFCSYGL 0 0 # .. getting handled
NNSGLFFLCGN 0 0
NSGLFFLCGNG 0 0
GVYKGFPPKWS 0 0
TNLRSFIHKVT 0 0
...
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
VLIKLFCVHTK 0 0
DVQIRFQPQL 0 1 # ...F{0,5}

Check out this Perl solution
perl -lne ' if (/^[^>]/) { while(/(?<=(\w{5}))F(?=(\w{5}))/g) { $x="$1F$2";$e=()=$x=~/E/g; $d=()=$x=~/D/g; print "$x $e $d" } } else { print }' 5letter.txt
EDIT1:
DVQIRFQPQL 0 1 # Edge case
For accommodating the edge case as mentioned by OP in the comments - the string to the right of F can be less than 5 letters if it is at the end of the line
perl -lne ' if (/^[^>]/) { while(/(?<=(.{5}))F(?=(.{0,5}))/g) { $x="$1F$2";$e=()=$x=~/E/g; $d=()=$x=~/D/g; print "$x $e $d" } } else { print }' 5letter.txt
For each line that doesn't start with >, use positive lookbehind to match 5 letter \w to the left of F and positive lookahead to match 5 letter \w to the right of F. Using while loop and /g on the match operator scan the line and for each match copy the $1F$2 into variable $x. Use list context and count the occurrences of E and D. Print the result finally.
with given inputs
$ perl -lne ' if (/^[^>]/) { while(/(?<=(.{5}))F(?=(.{0,5}))/g) { $x="$1F$2";$e=()=$x=~/E/g; $d=()=$x=~/D/g; print "$x $e $d" } } else { print }' 5letter.txt
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RQCSWFAGCTN 0 0
LLYQLFRNLFC 0 0
LFRNLFCSYGL 0 0
NNSGLFFLCGN 0 0
NSGLFFLCGNG 0 0
GVYKGFPPKWS 0 0
TNLRSFIHKVT 0 0
>sp|P13674|P4HA1_HUMAN Prolyl 4-hydroxylase subunit alpha-1 OS=Homo sapiens OX=9606 GN=P4HA1 PE=1 SV=2
GQKITFHGEGD 1 1
KDHAVFTRRGE 1 1
RGEDLFMCMDI 1 2
EALCGFQKPIS 1 0
RLIIEFKVNFP 1 0
EFKVNFPENGF 2 0
FPENGFLSPDK 1 1
>sp|Q7Z4N8|P4HA3_HUMAN Prolyl 4-hydroxylase subunit alpha-3 OS=Homo sapiens OX=9606 GN=P4HA3 PE=1 SV=1
ATTPQFPDMIL 0 1
RGHSHFVSDVV 0 1
SSDGQFALSGS 0 1
TTTRRFVGHTK 0 0
VLSVAFSSDNR 0 1
VSCVRFSPNSS 0 0
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
VLIKLFCVHTK 0 0
DVQIRFQPQL 0 1
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
LLLLAFLLLPR 0 0
KRCGGFLIRDD 0 2
LIRDDFVLTAA 0 2
EPTQQFIPVKR 1 0
YNPKNFSNDIM 0 1
>sp|Q9UHX1|PUF60_HUMAN Poly(U)-binding-splicing factor PUF60 OS=Homo sapiens OX=9606 GN=PUF60 PE=1 SV=1
GAEEKFKEIAE 4 0
RKREIFDRYGE 2 1
ANGTSFSYTFH 0 0
SFSYTFHGDPH 0 1
DPHAMFAEFFG 1 1
AMFAEFFGGRN 1 0
MFAEFFGGRNP 1 0
GGRNPFDTFFG 0 1
NPFDTFFGQRN 0 1
PFDTFFGQRNG 0 1
DIDDPFSGFPM 0 3
DPFSGFPMGMG 0 1
MGMGGFTNVNF 0 0
FTNVNFGRSRS 0 0
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
DGYVKFWQIYI 0 1
LSCLLFCDNHK 0 1
DPDVPFWRFLI 0 2
VPFWRFLITGA 0 0
LQTIRFSPDIF 0 1
FSPDIFSSVSV 0 1
EGHACFSSISE 2 0
SSISEFLLTHP 1 0
HPVLSFGIQVV 0 0
VLIKLFCVHTK 0 0
DVQIRFQPQLN 0 1
TAHEDFTFGES 2 1
HEDFTFGESRP 2 1
PAPADFLSLSS 0 1
MTPDAFMTPSA 0 1
>sp|O14683|P5I11_HUMAN Tumor protein p53-inducible protein 11 OS=Homo sapiens OX=9606 GN=TP53I11 PE=1 SV=2
ISLGIFPLPAG 0 0
SEQWKFQELSQ 2 0
EENEGFVKVTD 3 1
IENKAFDRNTE 2 1
NTESLFEELSS 3 0
AQRKRFTRVEM 1 0
SSIWQFFSRLF 0 0
SIWQFFSRLFS 0 0
FFSRLFSSSSN 0 0
$
PS:
$ echo "RNDDDDTSVCLGTRQCSWFAGCTNRTWNSSAVPLIGLPNTQDYKWVDRNSGLTWSGNDTCLYSCQNQTKGLLYQLFRNLFCSYGLTEAHGKWRCADASITNDKGHDGHRTPTWWLTGSNLTLSVNNSGLFFLCGNGVYKGFPPKWSGRCGLGYLVPSLT
RYLTLNASQITNLRSFIHKVTPHR" | perl -ne ' if (/^[^>]/) { $y=$_;while(/(.{10})/g) { $x=$1; $c++ for($x=~/F/g) ; print "$x $c\n"; $c=0 } } '
RNDDDDTSVC
LGTRQCSWFA 1
GCTNRTWNSS 0
AVPLIGLPNT 0
QDYKWVDRNS 0
GLTWSGNDTC 0
LYSCQNQTKG 0
LLYQLFRNLF 2
CSYGLTEAHG 0
KWRCADASIT 0
NDKGHDGHRT 0
PTWWLTGSNL 0
TLSVNNSGLF 1
FLCGNGVYKG 1
FPPKWSGRCG 1
LGYLVPSLT 0
RYLTLNASQI 0
TNLRSFIHKV 1
$

With any awk in any shell on any UNIX box:
$ cat tst.awk
/^>/ { print; next }
{
fpos = 0
while ( match(substr($0,fpos+1),/F/) ) {
fpos += RSTART
str = substr($0,fpos-5,11)
print str, gsub(/E/,"&",str), gsub(/D/,"&",str)
}
}
.
$ awk -f tst.awk file
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RQCSWFAGCTN 0 0
LLYQLFRNLFC 0 0
LFRNLFCSYGL 0 0
NNSGLFFLCGN 0 0
NSGLFFLCGNG 0 0
GVYKGFPPKWS 0 0
TNLRSFIHKVT 0 0
>sp|P13674|P4HA1_HUMAN Prolyl 4-hydroxylase subunit alpha-1 OS=Homo sapiens OX=9606 GN=P4HA1 PE=1 SV=2
GQKITFHGEGD 1 1
KDHAVFTRRGE 1 1
RGEDLFMCMDI 1 2
EALCGFQKPIS 1 0
RLIIEFKVNFP 1 0
EFKVNFPENGF 2 0
FPENGFLSPDK 1 1
>sp|Q7Z4N8|P4HA3_HUMAN Prolyl 4-hydroxylase subunit alpha-3 OS=Homo sapiens OX=9606 GN=P4HA3 PE=1 SV=1
ATTPQFPDMIL 0 1
RGHSHFVSDVV 0 1
SSDGQFALSGS 0 1
TTTRRFVGHTK 0 0
VLSVAFSSDNR 0 1
VSCVRFSPNSS 0 0
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
VLIKLFCVHTK 0 0
DVQIRFQPQL 0 1
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
LLLLAFLLLPR 0 0
KRCGGFLIRDD 0 2
LIRDDFVLTAA 0 2
EPTQQFIPVKR 1 0
YNPKNFSNDIM 0 1
>sp|Q9UHX1|PUF60_HUMAN Poly(U)-binding-splicing factor PUF60 OS=Homo sapiens OX=9606 GN=PUF60 PE=1 SV=1
GAEEKFKEIAE 4 0
RKREIFDRYGE 2 1
ANGTSFSYTFH 0 0
SFSYTFHGDPH 0 1
DPHAMFAEFFG 1 1
AMFAEFFGGRN 1 0
MFAEFFGGRNP 1 0
GGRNPFDTFFG 0 1
NPFDTFFGQRN 0 1
PFDTFFGQRNG 0 1
DIDDPFSGFPM 0 3
DPFSGFPMGMG 0 1
MGMGGFTNVNF 0 0
FTNVNFGRSRS 0 0
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
DGYVKFWQIYI 0 1
LSCLLFCDNHK 0 1
DPDVPFWRFLI 0 2
VPFWRFLITGA 0 0
LQTIRFSPDIF 0 1
FSPDIFSSVSV 0 1
EGHACFSSISE 2 0
SSISEFLLTHP 1 0
HPVLSFGIQVV 0 0
VLIKLFCVHTK 0 0
DVQIRFQPQLN 0 1
TAHEDFTFGES 2 1
HEDFTFGESRP 2 1
PAPADFLSLSS 0 1
MTPDAFMTPSA 0 1
>sp|O14683|P5I11_HUMAN Tumor protein p53-inducible protein 11 OS=Homo sapiens OX=9606 GN=TP53I11 PE=1 SV=2
ISLGIFPLPAG 0 0
SEQWKFQELSQ 2 0
EENEGFVKVTD 3 1
IENKAFDRNTE 2 1
NTESLFEELSS 3 0
AQRKRFTRVEM 1 0
SSIWQFFSRLF 0 0
SIWQFFSRLFS 0 0
FFSRLFSSSSN 0 0

This is an adaptation of the excellent solution of James Brown. The adaptation makes it POSIX compliant, and also corrects for the single case where two F values are less than 5 characters apart. Example:
...RQCSWFAGFCTNRQS...
^ ^
The first window should detect RQCSWFAGFCT while the second window should detect SWFAGFCTNRQ. In the proposed solution, it will only detect AGFCTNRQ, or it might not detect the second F at all. (depending on the usage of .{0,5}F.{0,5} or .{5}F.{0,5} as a regex.
awk '
NR%2 {print; next } # print every odd record
{ # the even records are processed
seq=$0; l=lseq=length($0)
while(match(seq,/F/)) { # find `F`
n = l - lseq + RSTART # get position in $0
print s=substr($0,n-5,(n<6?n+5:11)), # print match and
# correct if F is in the first 5
gsub(/E/,"E",s), # count of Es
gsub(/D/,"D",s) # count of Ds
seq=substr(seq,RSTART+1) # shorten the search string
lseq=lseq-RSTART
}
}' file.fasta
You might be also interested in BioAwk, it is an adapted version of awk which is tuned to process FASTA files.
This gives the result:
bioawk -c fastx '{ print ">" $name }
{ tmp=$seq; l=ltmp=length($seq)
while(match(tmp,/F/)) {
n=l-ltmp+RSTART
print s=substr($seq,n,(n<6?n+5:11)),
gsub(/E/,"E",s),
gsub(/D/,"D",s)
tmp=substr(tmp,RSTART+1)
ltmp=ltmp-RSTART
}}' file.fasta
Here $name is the sequence name (everything after >), and $seq is the complete sequence, even if you have a sequence spanning multiple lines.
Note: BioAwk is based on Brian Kernighan's awk which is documented in "The AWK Programming Language",
by Al Aho, Brian Kernighan, and Peter Weinberger
(Addison-Wesley, 1988, ISBN 0-201-07981-X)
. I'm not sure if this version is compatible with POSIX.

Related

For each unique occurrence in field, transform each unique occurrence in another field in a different column

I have a file
splice_region_variant,intron_variant A1CF 1
3_prime_UTR_variant A1CF 18
intron_variant A1CF 204
downstream_gene_variant A1CF 22
synonymous_variant A1CF 6
missense_variant A1CF 8
5_prime_UTR_variant A2M 1
stop_gained A2M 1
missense_variant A2M 15
splice_region_variant,intron_variant A2M 2
synonymous_variant A2M 2
upstream_gene_variant A2M 22
intron_variant A2M 308
missense_variant A4GNT 1
intron_variant A4GNT 21
5_prime_UTR_variant A4GNT 3
3_prime_UTR_variant A4GNT 7
This file is sorted by $2
for each occurrence of an unique element in $2, I wanna transform in a column each unique occurrence of an element in $1, with corresponding value in $3, or 0 if the record is not there. So that I have:
splice_region_variant,intron_variant 3_prime_UTR_variant intron_variant downstream_gene_variant synonymous_variant missense_variant 5_prime_UTR_variant stop_gained upstream_gene_variant
A1CF 1 18 204 22 6 8 0 0 0
A2M 2 0 308 0 2 15 1 1 22
A4GNT 0 7 21 0 0 22 3 0 0
test file:
a x 2
b,c x 4
dd x 3
e,e,t x 5
a b 1
cc b 2
e,e,t b 1
This is what I'm getting:
a b,c dd e,e,t cc
x 5 2 4 3
b 1 2 1
EDIT: This might be doing it but doesn't output 0s in blank fields
'BEGIN {FS = OFS = "\t"}
NR > 1 {data[$2][$1] = $3; blocks[$1]}
END {
PROCINFO["sorted_in"] = "#ind_str_asc"
# header
printf "gene"
for (block in blocks) {
printf "%s%s", OFS, block
}
print ""
# data
for (ts in data) {
printf "%s", ts
for (block in blocks) {
printf "%s%s", OFS, data[ts][block]
}
print ""
}
}' file
modified from https://unix.stackexchange.com/questions/424642/dynamic-transposing-rows-to-columns-using-awk-based-on-row-value
If you want to print 0 if a certain value is absent, you could do something like this:
val = data[ts][block] ? data[ts][block] : 0;
printf "%s%s", OFS, val

Filtering file according to the highest value in a column of each line

I have the following file:
gene.100079.0.5.p3 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 84.9
gene.100079.0.3.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 84.9
gene.100079.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 86.7
gene.100080.0.3.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
gene.100080.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
chr11_pilon3.g3568.t1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 74.9
chr11_pilon3.g3568.t2 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 76.7
The above file has some IDs which are similar
gene.100079.0.5.p3
gene.100079.0.3.p1
gene.100079.0.0.p1
By remaining only gene.100079 the IDs become identically. I would like to filter the above file in the following way:
chr11_pilon3.g3568.t1 = 74.9. IDs starting with chr get excluded from the comparison and they end up straight in the output.
gene.100079.0.0.p1 = 86.7 && gene.100079.0.5.p3 = 84.9 == gene.100079.0.3.p1 = 84.9. gene.100079.0.0.p1 has the highest value and therefore it should be in the output.
gene.100080.0.3.p1 = 99.9 == gene.100080.0.0.p1 = 99.9. Both IDs have the same value and therefore both should be in the output.
However, this awk script from #RavinderSingh13 and #anubhava returns the wrong results.
awk '{
if (/^gene\./) {
split($1, a, /\./)
k = a[1] "." a[2]
}
else
k = $1
}
!(k in max) || $13 >= max[k] {
if(!(k in max))
ord[++n] = k
else if (max[k] == $13) {
print
next
}
max[k] = $13
rec[k] = $0
}
END {
for (i=1; i<=n; ++i)
print rec[ord[i]]
}' file
Wrong output with the above script:
chr11_pilon3.g3568.t1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 74.9
chr11_pilon3.g3568.t2 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 76.7
gene.100079.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 86.7
gene.100079.0.3.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 84.9
gene.100080.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
gene.100080.0.3.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
As output I would like to get:
chr11_pilon3.g3568.t1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 74.9
chr11_pilon3.g3568.t2 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 76.7
gene.100079.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 86.7
gene.100080.0.3.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
gene.100080.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
I also tried to fix as show below but it didn't work:
awk '{
if (/^gene\./) {
split($1, a, /\./)
k = a[1] "." a[2]
}
else
k = $1
}
!(k in max) || $13 > max[k] {
max[k]=$13;
line[k]=$0
}
END {
for(i in line)
print line[i]
}'
Thank you in advance,
This seems to work correctly, assuming that the data is ordered so that all the lines with the same first two name components are grouped together in the data file. The order of those lines within the group doesn't matter.
As revised, the question now wants lines starting chr transferred to the output without any filtering. That is easily achieved — the rule matching /^chr/ provides that functionality.
#!/bin/sh
awk '
function dump_memo()
{
if (memo_num > 0)
{
for (i = 0; i < memo_num; i++)
print memo_line[i]
}
}
/^chr/ { print; next } # Do not process lines starting chr specially
{
split($1, a, ".")
key = a[1] "." a[2]
val = $NF
# print "# " key " = " val " (memo_key = " memo_key ", memo_val = " memo_val ")"
if (memo_key == key)
{
if (memo_val == val)
{
memo_line[memo_num++] = $0
}
else if (memo_val < val)
{
memo_val = val
memo_num = 0
memo_line[memo_num++] = $0
}
}
else
{
dump_memo()
memo_num = 0
memo_line[memo_num++] = $0
memo_key = key
memo_val = val
}
}
END { dump_memo() }' "$#"
When run on the data file shown in the question, the original output from the unrevised script was:
gene.100079.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 86.7
gene.100080.0.3.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
gene.100080.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
chr11_pilon3.g3568.t2 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 76.7
The main difference between this and what was requested is the sort order. If you need the data in sorted order, pipe the output of the script through sort.
With the revised script (with the /^chr/ rule) is:
gene.100079.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 86.7
chr11_pilon3.g3568.t1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 74.9
chr11_pilon3.g3568.t2 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 76.7
gene.100080.0.3.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
gene.100080.0.0.p1 transcript:OIS96097 82.2 169 30 0 1 169 4 172 1.3e-75 283.1 99.9
Again, if you want the data in some specific order, apply a sort to the output.

how can I exclude some data based on another data

I have two data, 1.txt and 2.txt, I am trying to remove those that are in 1.txt from the 2.txt
1.txt is
P13674
Q7Z4N8
O14683
Q9UHX1
and 2.txt is the following
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RNDDDDTSVCLGTRQCSWFAGCTNRTWNSSAVPLIGLPNTQDYKWVDRNSGLTWSGNDTCLYSCQNQTKGLLYQLFRNLFCSYGLTEAHGKWRCADASITNDKGHDGHRTPTWWLTGSNLTLSVNNSGLFFLCGNGVYKGFPPKWSGRCGLGYLVPSLTRYLTLNASQITNLRSFIHKVTPHR
>sp|P13674|P4HA1_HUMAN Prolyl 4-hydroxylase subunit alpha-1 OS=Homo sapiens OX=9606 GN=P4HA1 PE=1 SV=2
VECCPNCRGTGMQIRIHQIGPGMVQQIQSVCMECQGHGERISPKDRCKSCNGRKIVREKKILEVHIDKGMKDGQKITFHGEGDQEPGLEPGDIIIVLDQKDHAVFTRRGEDLFMCMDIQLVEALCGFQKPISTLDNRTIVITSHPGQIVKHGDIKCVLNEGMPIYRRPYEKGRLIIEFKVNFPENGFLSPDKLSLLEKLLPERKEVEE
>sp|Q7Z4N8|P4HA3_HUMAN Prolyl 4-hydroxylase subunit alpha-3 OS=Homo sapiens OX=9606 GN=P4HA3 PE=1 SV=1
MTEQMTLRGTLKGHNGWVTQIATTPQFPDMILSASRDKTIIMWKLTRDETNYGIPQRALRGHSHFVSDVVISSDGQFALSGSWDGTLRLWDLTTGTTTRRFVGHTKDVLSVAFSSDNRQIVSGSRDKTIKLWNTLGVCKYTVQDESHSEWVSCVRFSPNSSNPIIVSCGWDKLVKVWNLANCKLK
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
IQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQL
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
MQPILLLLAFLLLPRADAGEIIGGHEAKPHSRPYMAYLMIWDQKSLKRCGGFLIRDDFVLTAAHCWGSSINVTLGAHNIKEQEPTQQFIPVKRPIPHPAYNPKNFSNDIMLLQLERKAKRTRAVQPLRLPSNKAQVKPGQTCSVAGWGQTAPLGKHSHTLQEVKMTVQEDRKCES
>sp|Q9UHX1|PUF60_HUMAN Poly(U)-binding-splicing factor PUF60 OS=Homo sapiens OX=9606 GN=PUF60 PE=1 SV=1
MGKDYYQTLGLARGASDEEIKRAYRRQALRYHPDKNKEPGAEEKFKEIAEAYDVLSDPRKREIFDRYGEEGLKGSGPSGGSGGGANGTSFSYTFHGDPHAMFAEFFGGRNPFDTFFGQRNGEEGMDIDDPFSGFPMGMGGFTNVNFGRSRSAQEPARKKQDPPVTHDLRVSLEEIYSGCTKKMKISHK
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
IVVKGHSTCLSEGALSPDGTVLATASHDGYVKFWQIYIEGQDEPRCLHEWKPHDGRPLSCLLFCDNHKKQDPDVPFWRFLITGADQNRELKMWCTVSWTCLQTIRFSPDIFSSVSVPPSLKVCLDLSAEYLILSDVQRKVLYVMELLQNQEEGHACFSSISEFLLTHPVLSFGIQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQLNPDVVAPLPTHTAHEDFTFGESRPELGSEGLGSAAHGSQPDLRRIVELPAPADFLSLSSETKPKLMTPDAFMTPSASLQQITASPSSSSSGSSSSSSSSSSSLTAVSAMSSTSAVDPSLTRPPEELTLSPKLQLDGSLTMSSSGSLQASPRGLLPGLLPAPADKLTPKGPGQVPTATSALSLELQEVEP
>sp|O14683|P5I11_HUMAN Tumor protein p53-inducible protein 11 OS=Homo sapiens OX=9606 GN=TP53I11 PE=1 SV=2
MIHNYMEHLERTKLHQLSGSDQLESTAHSRIRKERPISLGIFPLPAGDGLLTPDAQKGGETPGSEQWKFQELSQPRSHTSLKVSNSPEPQKAVEQEDELSDVSQGGSKATTPASTANSDVATIPTDTPLKEENEGFVKVTDAPNKSEISKHIEVQVAQETRNVSTGSAENEEKSEVQAIIESTPELDMDKDLSGYKGSSTPTKGIENKAFDRNTESLFEELSSAGSGLIGDVDEGADLLGMGREVENLILENTQLLETKNALNIVKNDLIAKVDELTCEKDVLQGELEAVKQAKLKLEEKNRELEEELRKARAEAEDARQKAKDDDDSDIPTAQRKRFTRVEMARVLMERNQYKERLMELQEAVRWTEMIRASRENPAMQEKKRSSIWQFFSRLFSSSSNTTKKPEPPVNLKYNAPTSHVTPSVK
the output will look like this
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RNDDDDTSVCLGTRQCSWFAGCTNRTWNSSAVPLIGLPNTQDYKWVDRNSGLTWSGNDTCLYSCQNQTKGLLYQLFRNLFCSYGLTEAHGKWRCADASITNDKGHDGHRTPTWWLTGSNLTLSVNNSGLFFLCGNGVYKGFPPKWSGRCGLGYLVPSLTRYLTLNASQITNLRSFIHKVTPHR
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
IQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQL
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
MQPILLLLAFLLLPRADAGEIIGGHEAKPHSRPYMAYLMIWDQKSLKRCGGFLIRDDFVLTAAHCWGSSINVTLGAHNIKEQEPTQQFIPVKRPIPHPAYNPKNFSNDIMLLQLERKAKRTRAVQPLRLPSNKAQVKPGQTCSVAGWGQTAPLGKHSHTLQEVKMTVQEDRKCES
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
IVVKGHSTCLSEGALSPDGTVLATASHDGYVKFWQIYIEGQDEPRCLHEWKPHDGRPLSCLLFCDNHKKQDPDVPFWRFLITGADQNRELKMWCTVSWTCLQTIRFSPDIFSSVSVPPSLKVCLDLSAEYLILSDVQRKVLYVMELLQNQEEGHACFSSISEFLLTHPVLSFGIQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQLNPDVVAPLPTHTAHEDFTFGESRPELGSEGLGSAAHGSQPDLRRIVELPAPADFLSLSSETKPKLMTPDAFMTPSASLQQITASPSSSSSGSSSSSSSSSSSLTAVSAMSSTSAVDPSLTRPPEELTLSPKLQLDGSLTMSSSGSLQASPRGLLPGLLPAPADKLTPKGPGQVPTATSALSLELQEVEP
I was trying to do it with bash like this
cat 1.txt | grep -A 2.txt | sed -n -e '1,/>/ {/>/ !' > myout.txt
$ awk -F'|' 'NR==FNR{a[$0];next} /^>/{f=($2 in a ? 0 : 1)} f' 1.txt 2.txt
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RNDDDDTSVCLGTRQCSWFAGCTNRTWNSSAVPLIGLPNTQDYKWVDRNSGLTWSGNDTCLYSCQNQTKGLLYQLFRNLFCSYGLTEAHGKWRCADASITNDKGHDGHRTPTWWLTGSNLTLSVNNSGLFFLCGNGVYKGFPPKWSGRCGLGYLVPSLTRYLTLNASQITNLRSFIHKVTPHR
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
IQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQL
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
MQPILLLLAFLLLPRADAGEIIGGHEAKPHSRPYMAYLMIWDQKSLKRCGGFLIRDDFVLTAAHCWGSSINVTLGAHNIKEQEPTQQFIPVKRPIPHPAYNPKNFSNDIMLLQLERKAKRTRAVQPLRLPSNKAQVKPGQTCSVAGWGQTAPLGKHSHTLQEVKMTVQEDRKCES
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
IVVKGHSTCLSEGALSPDGTVLATASHDGYVKFWQIYIEGQDEPRCLHEWKPHDGRPLSCLLFCDNHKKQDPDVPFWRFLITGADQNRELKMWCTVSWTCLQTIRFSPDIFSSVSVPPSLKVCLDLSAEYLILSDVQRKVLYVMELLQNQEEGHACFSSISEFLLTHPVLSFGIQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQLNPDVVAPLPTHTAHEDFTFGESRPELGSEGLGSAAHGSQPDLRRIVELPAPADFLSLSSETKPKLMTPDAFMTPSASLQQITASPSSSSSGSSSSSSSSSSSLTAVSAMSSTSAVDPSLTRPPEELTLSPKLQLDGSLTMSSSGSLQASPRGLLPGLLPAPADKLTPKGPGQVPTATSALSLELQEVEP
In case you want to print lines whose 2nd column is NOT coming in 1.txt then try following.
awk 'FNR==NR{a[$0];next} /^>/ {flag=$2 in a?1:0}flag' 1.txt FS="|" 2.txt
Above will print all the lines which are satisfying condition for > and coming after it, in case OP wants to print only 2 lines after > line then try following.
awk 'FNR==NR{a[$0];next} /^>/ {flag=$2 in a?1:0;count=2} flag && count-->0' 1.txt FS="|" 2.txt
something like this should work (not tested), needs gawk
$ awk 'NR==FNR {a[$1]; next}
!($2 in a) {print rt $0} {rt=RT}' file1 RS='(^|\n)>' FS='|' file2
If you want to try Perl, check below
perl -ne ' BEGIN {#x=map{chomp;$_} qx(cat 1.txt);$pat=join("|",#x) } print if not /$pat/ '
with inputs
$ perl -ne ' BEGIN {#x=map{chomp;$_} qx(cat 1.txt);$pat=join("|",#x) } print if not /$pat/ ' 2.txt
>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RNDDDDTSVCLGTRQCSWFAGCTNRTWNSSAVPLIGLPNTQDYKWVDRNSGLTWSGNDTCLYSCQNQTKGLLYQLFRNLFCSYGLTEAHGKWRCADASITNDKGHDGHRTPTWWLTGSNLTLSVNNSGLFFLCGNGVYKGFPPKWSGRCGLGYLVPSLTRYLTLNASQITNLRSFIHKVTPHR
VECCPNCRGTGMQIRIHQIGPGMVQQIQSVCMECQGHGERISPKDRCKSCNGRKIVREKKILEVHIDKGMKDGQKITFHGEGDQEPGLEPGDIIIVLDQKDHAVFTRRGEDLFMCMDIQLVEALCGFQKPISTLDNRTIVITSHPGQIVKHGDIKCVLNEGMPIYRRPYEKGRLIIEFKVNFPENGFLSPDKLSLLEKLLPERKEVEE
MTEQMTLRGTLKGHNGWVTQIATTPQFPDMILSASRDKTIIMWKLTRDETNYGIPQRALRGHSHFVSDVVISSDGQFALSGSWDGTLRLWDLTTGTTTRRFVGHTKDVLSVAFSSDNRQIVSGSRDKTIKLWNTLGVCKYTVQDESHSEWVSCVRFSPNSSNPIIVSCGWDKLVKVWNLANCKLK
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
IQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQL
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
MQPILLLLAFLLLPRADAGEIIGGHEAKPHSRPYMAYLMIWDQKSLKRCGGFLIRDDFVLTAAHCWGSSINVTLGAHNIKEQEPTQQFIPVKRPIPHPAYNPKNFSNDIMLLQLERKAKRTRAVQPLRLPSNKAQVKPGQTCSVAGWGQTAPLGKHSHTLQEVKMTVQEDRKCES
MGKDYYQTLGLARGASDEEIKRAYRRQALRYHPDKNKEPGAEEKFKEIAEAYDVLSDPRKREIFDRYGEEGLKGSGPSGGSGGGANGTSFSYTFHGDPHAMFAEFFGGRNPFDTFFGQRNGEEGMDIDDPFSGFPMGMGGFTNVNFGRSRSAQEPARKKQDPPVTHDLRVSLEEIYSGCTKKMKISHK
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
IVVKGHSTCLSEGALSPDGTVLATASHDGYVKFWQIYIEGQDEPRCLHEWKPHDGRPLSCLLFCDNHKKQDPDVPFWRFLITGADQNRELKMWCTVSWTCLQTIRFSPDIFSSVSVPPSLKVCLDLSAEYLILSDVQRKVLYVMELLQNQEEGHACFSSISEFLLTHPVLSFGIQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQLNPDVVAPLPTHTAHEDFTFGESRPELGSEGLGSAAHGSQPDLRRIVELPAPADFLSLSSETKPKLMTPDAFMTPSASLQQITASPSSSSSGSSSSSSSSSSSLTAVSAMSSTSAVDPSLTRPPEELTLSPKLQLDGSLTMSSSGSLQASPRGLLPGLLPAPADKLTPKGPGQVPTATSALSLELQEVEP
MIHNYMEHLERTKLHQLSGSDQLESTAHSRIRKERPISLGIFPLPAGDGLLTPDAQKGGETPGSEQWKFQELSQPRSHTSLKVSNSPEPQKAVEQEDELSDVSQGGSKATTPASTANSDVATIPTDTPLKEENEGFVKVTDAPNKSEISKHIEVQVAQETRNVSTGSAENEEKSEVQAIIESTPELDMDKDLSGYKGSSTPTKGIENKAFDRNTESLFEELSSAGSGLIGDVDEGADLLGMGREVENLILENTQLLETKNALNIVKNDLIAKVDELTCEKDVLQGELEAVKQAKLKLEEKNRELEEELRKARAEAEDARQKAKDDDDSDIPTAQRKRFTRVEMARVLMERNQYKERLMELQEAVRWTEMIRASRENPAMQEKKRSSIWQFFSRLFSSSSNTTKKPEPPVNLKYNAPTSHVTPSVK
$
That was a bit tricky. Here you go.
grep -v -f <(sed -e 's/^\(.*\)$/\^>sp|\1|/' 1.txt) 2.txt | sed -ne '/^>/{p;n;p}'
The regular expressions (regex) are in the old (rather than revised/extended) POSIX style. The first regex, /^\(.*\)$/, matches each line of 1.txt to change, for example, P13674 to ^>sp|P13674|. The last, as you see, matches the beginning of a line in 2.txt. You could omit the first pattern, just typing grep -v -f 1.txt 2.txt | sed ..., and that would still practically probably work. I just thought it neater to match the beginning of a line more precisely.
The second regex, /^>/, distinguishes lines that begin with > from those that do not, because these two kinds of line want different handling.
By the way, I agree with you. The Awk solution is probably preferable. However, since you had started with Grep, my solution has followed in that vein.

Collada skeleton and controller relation

I am developing a collada loader for android OpenGL ES2, the scene has many meshes and lights which I can load them, now I am working on loding skeletons and animations, I can parse skeletons from visual_scene node and store them in a list of Skeleton class which has an Id and a Joint list, I parse the controllers from library_controllers which I can link with the mesh throw rhe url of the instance_controller of the visual scene node, now I want to link the controller with the skeleton for example:
the skeleton part in the visual_scene library is:
<node id="Armature_001" name="Armature_001" type="NODE">
<translate sid="location">0 5 -3.883436</translate>
<rotate sid="rotationZ">0 0 1 0</rotate>
<rotate sid="rotationY">0 1 0 0</rotate>
<rotate sid="rotationX">1 0 0 0</rotate>
<scale sid="scale">1 1 1</scale>
<node id="Bone" name="Bone" sid="Bone" type="JOINT">
<matrix sid="transform">1 0 0 0 0 0 -1 0 0 1 0 0 0 0 0 1</matrix>
<node id="Bone_001" name="Bone.001" sid="Bone_001" type="JOINT">
<matrix sid="transform">1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1</matrix>
</node>
</node>
</node>
and the mesh from the visual_scene is:
<node id="Cube" name="Cube" type="NODE">
<translate sid="location">0 0 0</translate>
<rotate sid="rotationZ">0 0 1 0</rotate>
<rotate sid="rotationY">0 1 0 0</rotate>
<rotate sid="rotationX">1 0 0 0</rotate>
<scale sid="scale">1 1 1</scale>
<instance_controller url="#Armature_001_Cube-skin">
<skeleton>#Bone</skeleton>
<bind_material>
<technique_common>
<instance_material symbol="Material_001-material" target="#Material_001-material"/>
</technique_common>
</bind_material>
</instance_controller>
</node>
and the controller from library_controllers is:
<controller id="Armature_Cube_001-skin" name="Armature">
<skin source="#Cube_001-mesh">
<bind_shape_matrix>1 0 0 0 0 1 0 -5 0 2.78181e-8 3 -1.39091e-7 0 0 0 1</bind_shape_matrix>
<source id="Armature_Cube_001-skin-joints">
<Name_array id="Armature_Cube_001-skin-joints-array" count="2">Bone Bone_002</Name_array>
<technique_common>
<accessor source="#Armature_Cube_001-skin-joints-array" count="2" stride="1">
<param name="JOINT" type="name"/>
</accessor>
</technique_common>
</source>
<source id="Armature_Cube_001-skin-bind_poses">
<float_array id="Armature_Cube_001-skin-bind_poses-array" count="32">1 0 0 0 0 0 -1 2.5 0 1 0 5 0 0 0 1 1 0 0 0 0 0 -1 1.5 0 1 0 5 0 0 0 1</float_array>
<technique_common>
<accessor source="#Armature_Cube_001-skin-bind_poses-array" count="2" stride="16">
<param name="TRANSFORM" type="float4x4"/>
</accessor>
</technique_common>
</source>
<source id="Armature_Cube_001-skin-weights">
<float_array id="Armature_Cube_001-skin-weights-array" count="20">1 0.9464464 0.05355352 1 0.9444246 0.05557531 1 0.9444246 0.05557531 1 0.9464464 0.05355352 0.02067142 0.9793285 0.02056819 0.9794319 0.02067142 0.9793285 0.02056819 0.9794319</float_array>
<technique_common>
<accessor source="#Armature_Cube_001-skin-weights-array" count="20" stride="1">
<param name="WEIGHT" type="float"/>
</accessor>
</technique_common>
</source>
<joints>
<input semantic="JOINT" source="#Armature_Cube_001-skin-joints"/>
<input semantic="INV_BIND_MATRIX" source="#Armature_Cube_001-skin-bind_poses"/>
</joints>
<vertex_weights count="12">
<input semantic="JOINT" source="#Armature_Cube_001-skin-joints" offset="0"/>
<input semantic="WEIGHT" source="#Armature_Cube_001-skin-weights" offset="1"/>
<vcount>1 2 1 2 1 2 1 2 2 2 2 2 </vcount>
<v>1 0 0 1 1 2 1 3 0 4 1 5 1 6 0 7 1 8 1 9 0 10 1 11 0 12 1 13 0 14 1 15 0 16 1 17 0 18 1 19</v>
</vertex_weights>
</skin>
</controller>
my question if there are many meshes which have different skeletons and controllers can I link controller and the skeleton from Id string
Try AssimpLib, supports Collada with skeletal animations well, it do all the hard work

Extract date from date time - change . to , and print sum up of different field

aNumber bNumber startDate cost balanceAfter trafficCase Operator unknown3 MainAmount BALANCEBEFORE
22676239633 433 2014-07-02 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-02 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-02 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-02 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
22665799922 70110055 2014-07-03 10:16:45.000 20,00 0.50 0 Telmob 126260244 20.0000 0.5000
22676239633 433 2014-07-03 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-04 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-04 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-05 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
Here is a sample of the data I have. I want to sum up cost, balanceAfter, MainAmount and BALANCEBEFORE at each time the date changed but my concern is I have date combined with time and my decimal separator is dot instead of comma so my awk script can't perform the operation.
Can I have an AWK script which will first extract only the date so in the end I will have an output looking like:
Date Cost balanceAfter MainAmount BALANCEBEFORE
02/07/2014 2,00 379,3 0 379,3
03/07/2014 20,00 0,7 20 0,7
04/07/2014 2,00 309,6 0 309,6
05/07/2014 0,00 69,5 0 69,5
HERE IS MY AWK SCRIPT
awk -F 'NR==1 {header=$0; next} {a[$3]+=$4 a[$3]+=$5 a[$3]+=$9 a[$3]+=$10} END {for (i in a) {printf "%d\t%d\n", i, a[i]}; tot+=a[i]};' out.txt>output.doc
EDIT: Avoid pre-processing step as per Etan Reisner's suggestion to use $NF to work around differing numbers of tokens in Operator column.
$ cat data.txt
aNumber bNumber startDate cost balanceAfter trafficCase Operator unknown3 MainAmount BALANCEBEFORE
22676239633 433 2014-07-02 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-02 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-02 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-02 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
22665799922 70110055 2014-07-03 10:16:45.000 20,00 0.50 0 Telmob 126260244 20.0000 0.5000
22676239633 433 2014-07-03 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-04 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-04 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-05 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
$ cat so2.awk
NR > 1 {
cost = $5;
balanceAfter = $6;
mainAmount = $(NF - 1);
balanceBefore = $NF;
sub(",", ".", cost);
sub(",", ".", balanceAfter);
sub(",", ".", mainAmount);
sub(",", ".", balanceBefore);
dateCost[$3] += cost;
dateBalanceAfter[$3] += balanceAfter;
dateMainAmount[$3] += mainAmount;
dateBalanceBefore[$3] += balanceBefore;
}
END {
printf("%s\t%s\t%s\t%s\t%s\n", "Date", "Cost", "BalanceAfter", "MainAmount", "BalanceBefore");
for (i in dateCost) {
printf("%s\t%f\t%f\t%f\t%f\n", i, dateCost[i], dateBalanceAfter[i], dateMainAmount[i], dateBalanceBefore[i]);
}
}
$ awk -f so2.awk data.txt
Date Cost BalanceAfter MainAmount BalanceBefore
2014-07-02 2.000000 379.300000 0.000000 379.300000
2014-07-03 20.000000 0.700000 20.000000 0.700000
2014-07-04 2.000000 309.600000 0.000000 309.600000
2014-07-05 0.000000 69.500000 0.000000 69.500000
This requires no pre-processing of the file:
awk '
BEGIN {print "Date Cost BalanceAfter MainAmount BalanceBefore"}
NR == 1 {next}
function showday() {
printf "%s\t%.2f\t%.1f\t%d\t%.1f\n", date, cost, bAfter, main, bBefore
}
date != $3 {
if (date) showday()
date = $3
cost = bAfter = main = bBefore = 0
}
{
sub(/,/, ".", $5)
cost += $5
bAfter += $6
main += $(NF-1)
bBefore += $NF
}
END {showday()}
' file | column -t
Date Cost BalanceAfter MainAmount BalanceBefore
2014-07-02 2.00 379.3 0 379.3
2014-07-03 20.00 0.7 20 0.7
2014-07-04 2.00 309.6 0 309.6
2014-07-05 0.00 69.5 0 69.5