IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lua Discussion :

Utilisation de la fonction io.popen() en combinaison avec une commande système


Sujet :

Lua

  1. #1
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut Utilisation de la fonction io.popen() en combinaison avec une commande système
    Bonjour !

    Je vous propose un script qui montre comment on peut utiliser la fonction io.popen() en combinaison avec la commande Windows findstr, pour scruter le contenu d'un ensemble de fichiers et obtenir la liste des fichiers dans laquelle une certaine chaîne est trouvée.

    C'est intéressant de pouvoir combiner la puissance (ou la simplicité, si vous préférez) des commandes système avec le confort d'un script Lua. Si vous avez fait d'autres trouvailles de ce genre, je serais curieux de les connaître.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    -- Fonction qui renvoie la liste de tous les fichiers d'un même répertoire
    -- contenant une chaîne donnée. Exploite la commande Windows "findstr".
     
    function findstring(str, path)
      local i, t, popen = 0, {}, io.popen
      for filename in popen('findstr /m /c:"' .. str .. '" ' .. path):lines() do
        i = i + 1
        t[i] = filename
      end
      return t
    end
     
    -- Fonction pour extraire le chemin d'un nom de fichier. Ici on s'en servira
    -- pour obtenir le répertoire du script lui-même.
     
    function extractfilepath(filename)
      return string.sub(filename, string.find(filename, ".+\\"))
    end
     
    -- Liste de tous les scripts Lua de ce répertoire contenant la chaîne "if".
     
    local t = findstring('if', extractfilepath(arg[0]) .. '*.lua')
     
    for i = 1, #t do
      print(t[i])
    end
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Un autre exemple, basé cette fois sur la commande forfiles. Le script ci-dessous récupère dans des variables un ensemble d'informations sur tous les fichiers d'un répertoire : nom, extension, chemin absolu, chemin relatif, si c'est un dossier, taille en octets, date, heure.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    function forfiles(path)
      local i, t, popen = 0, {}, io.popen
      local s = 'cmd /c echo @FNAME;@EXT;@PATH;@RELPATH;@ISDIR;@FSIZE;@FDATE;@FTIME'
      local cmd = string.format('forfiles /p %s /s /m * /c "%s"', path, s)
      for filename in popen(cmd):lines() do
        i = i + 1
        t[i] = filename
      end
      return t
    end
     
    function extractfilepath(filename)
      return string.sub(filename, string.find(filename, '.+\\'))
    end
     
    local t = forfiles(extractfilepath(arg[0]))
     
    io.output('output.txt')
     
    for i = 1, #t do
      local _, _, fname, ext, path, relpath, isdir, fsize, fdate, ftime = string.find(
        t[i],
        '"(.+)";"(.+)";"(.+)";"(.+)";(.+);(.+);(.+);(.+)'
      )
      if _ then
        io.write(string.format(
          string.rep('%s\n', 8),
          fname, ext, path, relpath, isdir, fsize, fdate, ftime
        ))
      end
    end
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Un dernier exemple "pour la route". Cette fois on exploite la commande tasklist pour obtenir une liste des processus actifs avec leur PID.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    function tasklist()
      local i, t, popen = 0, {}, io.popen
      local cmd = 'tasklist'
      for filename in popen(cmd):lines() do
        i = i + 1
        t[i] = filename
      end
      return t
    end
     
    local t = tasklist()
     
    io.output('tasklist.txt')
     
    for i = 1, #t do
      --io.write(t[i] .. '\n')
      local _, _, name, pid = string.find(t[i], '(%a+%.exe)%s+(%d+)')
      if _ then
        io.write(string.format('Name=%s PID=%s', name, pid) .. '\n')
      end
    end
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  4. #4
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Y a-t-il des utilisateurs de Lua sous Linux ? Je serais curieux de savoir si le script suivant peut-être adapté pour Linux. Le script utilise une commande système (dir) pour obtenir la liste des fichiers portant une certaine extension (en l'occurrence des codes sources en Pascal).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    -- correct-program-identifiers.lua
     
    -- Corrige les identifiants suivant le mot-clé "program" dans un programme en
    -- Pascal. Le nouvel identifiant est le nom du fichier.
    -- Dans cette version du script, l'opération est faite pour tous les fichiers
    -- portant l'extension *.pp et se trouvant dans le même répertoire que le script
    -- Lua.
     
    -- Testé sous Windows 8.1, avec l'interpréteur Lua 5.2. Le script fait appel à
    -- une commande système Windows.
     
    local simulation = true
    --local simulation = false
    local searchsubdirs = false
     
    function ExtractFilePath(filename)
      if string.find(filename, "\\") then
        local r = filename
        while string.sub(r, #r) ~= "\\" do
          r = string.sub(r, 1, -2)
        end
        return r
      else
        return ""
      end
    end
     
    function ChangeFileExt(aFilename, aNewExt)
      return string.gsub(aFilename, "%.%a+", aNewExt) 
    end
     
    -- http://www.lua.org/pil/20.4.html
     
    function NoCase(s)
      s = string.gsub(s, "%a", function (c)
            return string.format("[%s%s]", string.lower(c),
                                           string.upper(c))
          end)
      return s
    end
     
    function CorrectProgramIdentifier(aFilename)
      local PATTERN = NoCase("program ") .. ".-" .. NoCase(";")
      io.input(aFilename)
      -- lit le contenu du fichier dans une chaîne
      local s = io.read("*a")
      -- cherche dans la chaîne le motif
      if string.match(s, PATTERN) then
        -- remplace le motif
        s = string.gsub(s, PATTERN, "program " .. ChangeFileExt(aFilename, "") .. ";")
        -- remplace le fichier
        if simulation then
          print(s)
        else
          io.output(aFilename)
          io.write(s)
        end;
      end
    end
     
    function ExecAndCapture(aCommand)
      local i, t, popen = 0, {}, io.popen
      for s in popen(aCommand):lines() do
        i = i + 1
        t[i] = s
      end
      return t
    end
     
    --local command = "dir c:\\atelier\\pascal\\regularexpressions\\regexpr\\*.pp /a-d /b /s"
     
    local ext = ".pp"
    local command = "dir " .. ExtractFilePath(arg[0]) .. "*" .. ext .. " /a-d /b"
    if searchsubdirs then
      command = command .. " /s"
    end
     
    if simulation then
      print(command)
      os.execute("pause")
    end
     
    local myfiles = ExecAndCapture(command)
     
    for i = 1, #myfiles do
      print(myfiles[i])
      CorrectProgramIdentifier(myfiles[i])
    end
     
    os.execute("pause")
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  5. #5
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Bonjour ! Je vous propose un petit script qui me rend service. Peut-être sera-t-il utile à quelqu'un d'autre ?

    C'est un script qui renomme tous les fichiers d'un répertoire (en l'occurrence les fichiers LXF). Le nom est remplacé par un numéro (en l'occurrence un numéro à trois chiffres). À adapter à vos besoins.

    Il y a une petite astuce dans le script qui consiste à demander à Windows les noms de fichier courts, pour éviter le problème qui surviendrait autrement avec les noms de fichiers contenant des accents.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    -- Renommage de tous les fichiers d'un répertoire sous Windows
    -- Dans son état actuel, le script renomme tous les fichiers *.LXF du répertoire courant. Le nom est
    -- remplacé par un numéro à trois chiffres.
     
    function Execute(aCommand)
      local i, result, popen = 0, {}, io.popen
      for line in popen(aCommand):lines() do
        i = i + 1
        result[i] = line
      end
      return result
    end
     
    --local files = Execute('dir /b *.lxf') -- Ne fonctionne pas s'il y a des accents dans les noms de fichiers.
    local files = Execute('for %x in (*.lxf) do @echo %~sx') -- Solution : utiliser les noms courts.
     
    for i = 1, #files do
      print(files[i])
      print(os.rename(files[i], string.format("%0.3d.lxf", i)))
    end
     
    os.execute("pause")
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/04/2013, 20h28
  2. Utilisation de la fonction de déploiement
    Par mchicoix dans le forum XMLRAD
    Réponses: 4
    Dernier message: 01/03/2005, 15h35
  3. [LG]Utilisation de la fonction Random
    Par chloe95 dans le forum Langage
    Réponses: 1
    Dernier message: 01/03/2005, 15h20
  4. Utilisation de la fonction qsort
    Par Jsmeline dans le forum C
    Réponses: 8
    Dernier message: 28/01/2005, 13h40
  5. [LG]librairies : utiliser seulement quelques fonctions
    Par wwwroom dans le forum Langage
    Réponses: 13
    Dernier message: 14/05/2004, 23h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo