Lignes de copie UNIX au nouveau fichier SI une colonne correspond ET une autre a une valeur inférieure à 5×10 ^ -8

Question similaire à beaucoup de précédents (y compris le mien) mais je ne trouve pas la solution. Ceci est purement une erreur de syntaxe et je ne peux pas comprendre comment le faire fonctionner.

J’ai deux fichiers sous Unix. Dans le fichier 1 j’ai 5 colonnes et environ 6000 lignes. J’essaie de faire correspondre les lignes du fichier2 aux lignes du fichier1 SI la colonne 1 correspond exactement à AND si la valeur de la ligne 5 du fichier1 est inférieure à 0.00000005 pour ladite ligne.

fichier1:

SNPs Context Intergenic Risk Allele Frequency p-Value rs9747992 Intergenic 1 0.086 2.00E-07 rs2059865 Intron 0 0.235 3.00E-07 rs117020818 Intergenic 1 0.046 7.00E-07 rs1074145 Intergenic 1 0.162 4.00E-09 

fichier2:

 snpid hg18chr bp a1 a2 zscore pval CEUmaf rs3131972 1 742584 AG 0.289 0.7726 . rs3131969 1 744045 AG 0.393 0.6946 . rs3131967 1 744197 TC 0.443 0.658 . rs1048488 1 750775 TC -0.289 0.7726 . 

Je peux faire la première partie MAIS elle continue à produire un fichier plus grand que les deux premiers. Je ne suis pas sûr que ce soit un vrai fichier de résultats ou juste plein de doublons? Je ne peux pas non plus faire la commande “moins que”. J’ai essayé de le mettre dans la commande en tant que deuxième motif et de le faire passer comme suit:

 awk 'FNR==NR{a[$1]=$0;next}{if ($1 in a) {print $0}}' file1 file2 > output | awk '{if (a[$5] < 0.00000005)}' 

et

 awk 'FNR==NR{a[$1]=$0;next}{if ($1 in a && $5  output 

Les deux fois, il me donne le même fichier de taille qui est beaucoup plus grand que fichier1 ou fichier2. Si vous voulez des exemples de tableaux, veuillez simplement dire.

Solution provisoire:

Une solution provisoire que j’utilise consiste simplement à créer un nouveau fichier contenant uniquement des lignes de fichier1 qui ont cette valeur <0.00000005. Cela fonctionne bien mais je voudrais connaître ma réponse originale pour la postérité.

 awk '$5 file11 

Selon mes commentaires ci-dessus, si vous utilisez file2 en tant que liste de filtres, vous devez le charger dans le tableau a a[] .

J’ai composé un petit échantillon de la façon dont cela fonctionne, le test $28 < .000005 devrait être facile à append tel que vous l'avez dans votre code.

Avec fichier data1

 1 2 3 4 5 6 7 2 3 4 5 6 7 8 4 5 8 7 8 9 10 

et liste de fichiers

 3 

alors

 awk 'FNR==NR{a[$0]=$0;next} FNR!=NR{ if ($2 in a) print $0} #dbg END{for (x in a) print "x="x " a[x]=" a[x] }' searchList data1 

donne sortie

 2 3 4 5 6 7 8 

modifier Par notre conversation dans les commentaires, ma meilleure supposition sans voir votre résultat requirejs serait

J'ai ajouté un enregistrement supplémentaire dans le fichier 1 pour qu'il y ait une correspondance

 rs3131972 Intergenic 1 0.086 2.00E-07 awk '( FNR==NR && (sprintf("%.07f",$5) < .000000005) ) { a[$1]=$0 #dbg print "a["$1"]="a[$1] next } FNR!=NR{ #dbg print "$1="$1 if ($1 in a)print "Matched:" $0 }' file1 file2 

La sortie est maintenant

 Matched:rs3131972 1 742584 AG 0.289 0.7726 . 

IHTH

La réponse de Shellter est bonne. Le mien est plus sur ce que tu as fait de mal. Votre première tentative

 > awk 'FNR==NR{a[$1]=$0;next}{if ($1 in a) {print $0}} ' file1 file2 > output | awk '{if (a[$5] < 0.00000005)}' 

échoue parce que votre pipeline est incorrect. Vous devez tuyau awk | awk > output awk | awk > output pas awk >output | awk awk >output | awk . Ce dernier ne recevra aucune entrée et ne produira aucune sortie de la dernière étape du pipeline. De plus, la seconde instance d'Awk n'a aucune connaissance des variables que vous avez utilisées dans le premier.

De plus, vous semblez avoir un problème récurrent avec les fausses attelles dans Awk. La syntaxe générale est awk " condition 1 { action 1 } condition 2 { action 2 } ..." où vous pouvez omettre une condition pour effectuer une action sans condition ou omettre la partie action (avec les accolades) pour effectuer l'action par défaut { print $0 } . Mais ici, vous n'avez qu'une action, qui est cependant une condition, sans effets secondaires tels que l'impression de n'importe quoi. Vous voulez supprimer les accolades et le wrapper if .

Donc vous avez besoin

 awk 'FNR==NR{a[$1]=$0;next}{if ($1 in a) {print $0}}' file1 file2 | awk '$5 < 0.00000005' >output 

qui (conformément aux règles d’omission d’une condition ou d’une action, et avec un certain refactoring) peut être beaucoup plus simple à

 awk 'FNR==NR{a[$1]=$0;next} $1 in a' file1 file2 | awk '$5 < 0.00000005' >output 

Votre deuxième tentative est plus proche;

 > awk 'FNR==NR{a[$1]=$0;next} {if ($1 in a && $5 < 0.00000005)} {print $0}}' file1 file2 > output 

mais encore une fois, vous avez trop de crochets. L'attelle de fermeture après le if gâche tout! Donc, vous avez effectivement "if (condition)" alors rien (peut-être que cela devrait être une erreur de syntaxe!), Suivi d'un nouveau bloc avec une print inconditionnelle. Mais dans l'ensemble, c'est beaucoup mieux.

 awk 'FNR==NR{a[$1]=$0;next} {if ($1 in a && $5 < 0.00000005) print $0}' file1 file2 > output 

qui bien sûr peut être simplifié à

 awk 'FNR==NR{a[$1]=$0;next} ($1 in a) && $5 < 0.00000005' file1 file2 > output 

Répondez à cela en fonction de l’assistance de Shellters.

 awk -F $'\t' 'NR==FNR{if ($5 < 0.00000005){a[$1]=$0}} NR!=FNR{if ($1 in a) print $0}' file1 file2 > output 

Merci