2016-10-23 3 views
0

J'essaie de lire le nom de fichier et le filestamp pour les fichiers les plus récents de chacun des deux schémas de nommage comme vu dans le code. Je le code suivant, à peu près:Awk dans le sous-processus de Python donnant des expressions non valides Erreur "'"

#!/usr/bin/env python 
import string, subprocess, sys, os 
mypath = "/path/to/file" 


my_cmd = (["ls -lt --full-time " + mypath + "*DAI*.txt", 
      "ls -lt --full-time " + mypath + "*CA*.txt"] 
     ) 
getmostrecent_cmd = "head -n 1" 
getcols_cmd = "awk '{ print $6, $7, $9 }'" 

for cmd in my_cmd: 
    p1 = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) 
    p2 = subprocess.Popen(getmostrecent_cmd.split(), stdin=p1.stdout, stdout=subprocess.PIPE) 
    p3 = subprocess.Popen(getcols_cmd.split(), stdin=p2.stdout, stdout=subprocess.PIPE) 
    output = p3.communicate()[0] 

    print output 

qui me donne l'erreur suivante (s):

ls: cannot access /path/to/file/*DAI*.txt: No such file or directory 
awk: '{ 
awk:^invalid char ''' in expression 

ls: cannot access /path/to/file/*CA*.txt: No such file or directory 
awk: '{ 
awk:^invalid char ''' in expression 

Mais:

  1. je peux utiliser "ls -LT - full-time/path/to/file/*DAI*.txt "et obtenir un résultat dans le terminal. Pourquoi cause-t-il un problème avec le même chemin?
  2. La commande awk, lorsqu'elle est directement envoyée au sous-processus, fonctionne correctement; Par exemple. sous-processus.Popen (["awk", ....], stdin = ...., stdout = ....) a bien fonctionné. Mais maintenant je reçois un problème avec la citation unique. J'ai essayé le triple en citant la chaîne et en échappant à la guillemets simples.

Répondre

1

Je peux utiliser "ls -lt --full temps/chemin/vers/fichier/DAI txt" et obtenir un résultat dans le terminal. Pourquoi cause-t-il un problème avec le même chemin?

L'expansion Glob est effectuée par le shell. Par défaut, shell n'est pas impliqué dans le démarrage d'un nouveau sous-processus via Popen(). À cette fin, vous devez passer l'argument shell=True à lui:

p1 = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, shell=True) 
#               ^^^^^^^^^^ 

La commande awk, lorsqu'il est mis pour Subprocess directement, fonctionne très bien; Par exemple. sous-processus.Popen (["awk", ....], stdin = ...., stdout = ....) a bien fonctionné. Mais maintenant je reçois un problème avec la citation unique. J'ai essayé triple en citant la chaîne et en échappant à la guillemets simples.

Sur la ligne de commande shell les guillemets simples dans awk '{ print $6, $7, $9 }' sont nécessaires pour rendre la chaîne { print $6, $7, $9 } traité comme un seul argument (ainsi que pour empêcher l'expansion variable). Les guillemets simples sont supprimés par le shell et awk ne voit que la chaîne { print $6, $7, $9 }. Depuis Popen() par défaut ne comporte pas shell lors de l'exécution de la commande et sous-processus passe les arguments à la commande mot pour mot, vous n'avez pas besoin des guillemets simples:

subprocess.Popen(["awk", "{ print $6, $7, $9 }"], stdin=...., stdout=....) 
+0

Merci compagnon. Votre asnwer à 2 a beaucoup aidé. Pour 1, je n'étais pas censé utiliser shell = True. Ma solution de contournement consistait à extraire le chemin d'accès complet, puis grep pour DAI et CA. – DDauS