2017-08-08 1 views
1

Étant donné un fichier test.txt avec le contenu suivant:Exécuter commande bash dans la sortie awk et commande d'impression

ABC DEF GATTAG GHK 
ABC DEF GGCGTC GHK 
ABC DEF AATTCC GHK 

la 3ème colonne doit être modifiée, de sorte que la chaîne est complément inverse. Une partie de cela peut être fait avec une commande bash:

cat test.txt | cut -f3 | rev | tr ATGC TACG

CTAATC 
GACGCC 
GGAATT 

Comment cela peut-il être mis en œuvre avec awk?(il y a un script awk plus grand pour le traitement des dossiers, qui cette fonction sera ajoutée.)

Une façon possible que cela pourrait être fait est en exécutant rev | tr ATGC TACG à l'intérieur de awk, semblable à:

awk '{newVar=system("rev | tr ATGC TACG"$3); print $1 $2 newVar $4}' test.txt 

Cependant, cette version et diverses versions similaires ne fonctionnent pas. Quelqu'un peut-il signaler ce qui est incorrect?

Répondre

1

Il suffit de faire l'inversion de chaîne et de traduction dans awk lui-même:

$ awk ' 
    BEGIN { 
     old="ATGC" 
     new="TACG" 
     for (i=1;i<=length(old);i++) { 
      tr[substr(old,i,1)] = substr(new,i,1) 
     } 
    } 
    { 
     newVar="" 
     for (i=1;i<=length($3);i++) { 
      char = substr($3,i,1) 
      newVar = (char in tr ? tr[char] : char) newVar 
     } 
     print $1, $2, newVar, $4 
    } 
' file 
ABC DEF CTAATC GHK 
ABC DEF GACGCC GHK 
ABC DEF GGAATT GHK 

Si vous vous sentez vraiment un besoin ardent d'appeler un outil externe de awk et lire le résultat en arrière ce serait:

$ awk ' 
    { 
     cmd="echo \047" $3 "\047 | rev | tr \047ATGC\047 \047TACG\047" 
     newVar=((cmd | getline line) > 0 ? line : "failed") 
     close(cmd) 
     print $1, $2, newVar, $4 
    } 
' file 
ABC DEF CTAATC GHK 
ABC DEF GACGCC GHK 
ABC DEF GGAATT GHK 

mais vous devriez vous attendre à une baisse significative des performances et voir également les avertissements getline: http://awk.freeshell.org/AllAboutGetline.

+0

fyi: http://awk.freeshell.org/ ne fonctionne pas, trouvé un instantané sur https://web.archive.org/web/20170524214527/http://awk.freeshell.org/AllAboutGetline – Sundeep

+1

Ouais J'ai remarqué qu'il est parti il ​​y a environ un mois.J'avais commencé à utiliser cette référence après que awk.info soit parti. Peut-être que c'est mieux référencé dans la vue google groups du groupe usenet comp.lang.awk où je l'ai effectivement posté: https://groups.google.com/forum/message/raw?msg=comp.lang.awk/2TA76BVODz4/Q9TkehK_tWYJ –

+1

suggestion: peut être créer un github repo ou gist ou similaire, ou un wiki communautaire ici .. – Sundeep

0

si perl est correct:

$ perl -lane '$F[2]=~tr/ATGC/TACG/; $F[2]=reverse $F[2]; print join " ",@F' test.txt 
ABC DEF CTAATC GHK 
ABC DEF GACGCC GHK 
ABC DEF GGAATT GHK 
  • l'option -a couperait la ligne sur les espaces et enregistrez @F tableau
  • $F[2]=~tr/ATGC/TACG/ utilisation tr seulement pour la 3ème colonne
  • $F[2]=reverse $F[2] inverse la chaîne pour la 3ème colonne
  • print join " ",@F imprimer le tableau modifié avec un espace comme séparateur


peut aussi être écrit comme

perl -lane '$F[2]=reverse $F[2]=~tr/ATGC/TACG/r; print join " ",@F' test.txt 

ou en utilisant le code Perl dans la section de remplacement

perl -pe 's/^(\H+\h+){2}\K\H+/reverse $&=~tr|ATGC|TACG|r/e' test.txt