2016-12-26 3 views
3

J'ai obtenu une très bonne réponse ici sur la façon d'effacer une ligne/supprimer une ligne dans un fichier sans avoir à tronquer le fichier ou remplacer le fichier par une nouvelle version de la fichier, voici le code Python:Comment traduire ce code Python en Node.js

#!/usr/bin/env python 

import re,os,sys 
logfile = sys.argv[1] 
regex = sys.argv[2] 

pattern = re.compile(regex) 

with open(logfile,"r+") as f: 
    while True: 
     old_offset = f.tell() 
     l = f.readline() 
     if not l: 
      break 
     if pattern.search(l): 
      # match: blank the line 
      new_offset = f.tell() 
      if old_offset > len(os.linesep): 
       old_offset-=len(os.linesep) 
      f.seek(old_offset) 
      f.write(" "*(new_offset-old_offset-len(os.linesep))) 

ce script peut être appelé comme:

./clear-line.py <file> <pattern> 

pour des fins éducatives, je suis en train de comprendre si je peux écrire ceci dans Node.js. Je peux certainement lire un fichier avec Node.js ligne par ligne. Mais je ne suis pas sûr si Node.js a les appels équivalents pour tell/seek dans ce cas.

l'équivalent pour l'écriture est sûrement

https://nodejs.org/api/fs.html#fs_fs_write_fd_buffer_offset_length_position_callback

Voici ma tentative

#!/usr/bin/env node 

const readline = require('readline'); 
const fs = require('fs'); 

const file = process.argv[2]; 
const rgx = process.argv[3]; 

const fd = fs.openSync(file, 'r+'); 

const rl = readline.createInterface({ 
    input: fs.createReadStream(null, {fd: fd}) 
}); 

let position = 0; 

const onLine = line => { 

    position += line.length; 

    if (String(line).match(rgx)) { 

     let len = line.length; 

     rl.close(); 
     rl.removeListener('line', onLine); 

     // output the line that will be replaced/removed 
     process.stdout.write(line); 

     fs.write(fd, new Array(len + 1).join(' '), position, 'utf8', err => { 
      if (err) { 
       process.stderr.write(err.stack || err); 
       process.exit(1); 
      } 
      else { 
       process.exit(0); 
      } 

     }); 

    } 

}; 

rl.on('line', onLine); 

Ce n'est pas tout à fait raison - je ne pense pas que je calculais le décalage/la position correctement. Peut-être que quelqu'un qui connaît à la fois Python et Node peut m'aider. Je ne suis pas très familier avec le calcul de position/offset dans les fichiers, surtout en termes de tampons.

Voici les données dans un fichier texte avec lequel je travaille. Tout ce que je veux faire est de lire la première ligne qui n'est pas vide, puis supprimer cette ligne du fichier et écrire cette ligne sur stdout.

Cela pourrait vraiment toutes les données non-blancs, mais voici le JSON que je travaille avec:

{"dateCreated":"2016-12-26T09:52:03.250Z","pid":5371,"count":0,"uid":"7133d123-e6b8-4109-902b-7a90ade7c655","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:03.290Z","pid":5371,"count":1,"uid":"e881b0a9-8c28-42bb-8a9d-8109587777d0","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:03.390Z","pid":5371,"count":2,"uid":"065e51ff-14b8-4454-9ae5-b85152cfcb64","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:03.491Z","pid":5371,"count":3,"uid":"5af80a95-ff9d-4252-9c4e-0e421fd9320f","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:03.595Z","pid":5371,"count":4,"uid":"961e578f-288b-413c-b933-b791f833c037","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:03.696Z","pid":5371,"count":5,"uid":"a65cbf78-2ea1-4c3a-9beb-b4bf56e83a6b","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:03.799Z","pid":5371,"count":6,"uid":"d411e917-ad25-455f-9449-ae4d31c7b1ad","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:03.898Z","pid":5371,"count":7,"uid":"46f8841d-c86c-43f2-b440-8ab7feea7527","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:04.002Z","pid":5371,"count":8,"uid":"81b5ce7e-2f4d-4acb-884c-442c5ac4490f","isRead":false,"line":"foo bar baz"} 
{"dateCreated":"2016-12-26T09:52:04.101Z","pid":5371,"count":9,"uid":"120ff45d-74e7-464e-abd5-94c41e3cd089","isRead":false,"line":"foo bar baz"} 

Répondre

0

Ok, je pense que je l'ai eu, mais si quelqu'un a une boeuf avec ce s'il vous plaît ne hésitez à critiquer. C'est proche, mais il faut un réglage précis, je pense, il semble y avoir une erreur hors-par-ou quelque chose comme ça.

#!/usr/bin/env node 

const readline = require('readline'); 
const fs = require('fs'); 

const file = process.argv[2]; 
const rgx = new RegExp(process.argv[3]); 

const fd = fs.openSync(file, 'r+'); 

const rl = readline.createInterface({ 
    input: fs.createReadStream(null, {fd: fd}) 
}); 

let position = 0; 

const onLine = line => { 

    if (String(line).match(rgx)) { 

     let len = line.length; 

     rl.close(); 
     rl.removeListener('line', onLine); 

     // output the line that will be replaced/removed 
     process.stdout.write(line + '\n'); 

     fs.write(fd, new Array(len + 1).join(' '), position, 'utf8', 

      (err, written, string) => { 

      if (err) { 
       process.stderr.write(err.stack || err); 
       return process.exit(1); 
      } 
      else { 
       process.exit(0); 
      } 

     }); 

    } 

    position += (line.length + 1); // 1 is length of \n character 

}; 

rl.on('line', onLine); 
+0

J'étais sur le point de poster une réponse mentionnant 'fs.createReadStream' ... car je pense que vous avez la bonne idée là-bas. Pour l'équivalent du tell de Python, il existe plusieurs façons de l'approcher (par exemple 'fs.readSync' pourrait fonctionner). 'fs.ReadSteam' a quelques fonctions que vous pouvez utiliser pour faire ce que vous essayez. –

+0

merci oui, il est proche de travailler mais pas tout à fait 100% –

+0

Je ne suis pas sûr si je calcule la position correctement. Je suppose que la position sera le nombre de caractères dans le fichier. –

1

Vous devez prendre en considération le caractère de nouvelle ligne à la fin de chaque ligne, qui ne figure pas dans la « ligne » vous obtenez via le module readline. Autrement dit, vous devez mettre à jour la position à position += (line.length + 1), puis lors de l'écriture, utilisez simplement position (sans le -1).

+0

merci je pense que c'est correct –

+0

toute idée de la différence entre les octets (octets lus) et la position (la façon dont je l'ai calculé)? Dans ce cas, il semble fonctionner si je place la position égale au nombre de caractères dans le fichier jusqu'au point. Mais si je fais une position égale au nombre d'octets lus, cela ne fonctionne pas et le nombre d'octets lus est plus grand d'une certaine marge que le nombre de caractères, il apparaît. –

+0

C'est juste une représentation différente de la quantité de données - les octets lus sont la quantité d'octets utilisée pour stocker cette chaîne tandis que la position représente le nombre de caractères dans cette chaîne spécifique. Vous pouvez également lire ce fichier directement via le module fs du nœud et travailler votre chemin avec des octets. Cependant, readline est un module beaucoup plus agréable et de niveau supérieur pour travailler avec votre but spécifique. –