2016-12-26 3 views
3

Ich habe hier eine sehr nette Antwort darüber, wie man eine Zeile löscht/löscht eine Zeile in einer Datei, ohne die Datei abzuschneiden oder die Datei durch eine neue Version des Datei, hier ist der Python-Code:Wie man diesen Python - Code in Node.js übersetzt

#!/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))) 

dieses Skript kann wie aufgerufen werden:

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

für pädagogische Zwecke, ich versuche, um herauszufinden, ob ich das in Node.js. schreiben Ich kann sicherlich eine Datei mit Node.js Zeile für Zeile lesen. Aber ich bin mir nicht sicher, ob Node.js in diesem Fall die entsprechenden Aufrufe für Tell/Seek hat.

das Äquivalent für das Schreiben ist sicherlich

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

Hier ist mein Versuch

#!/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); 

Es ist nicht ganz richtig - ich glaube nicht, dass ich die Offset/Position richtig bin zu berechnen. Vielleicht kann mir jemand helfen, der sowohl Python als auch Node kennt. Ich bin nicht sehr vertraut mit der Berechnung von Position/Offset in Dateien, insbesondere in Bezug auf Puffer.

Hier sind die Daten in einer Textdatei, mit der ich arbeite. Ich möchte nur die erste Zeile lesen, die nicht leer ist, und dann diese Zeile aus der Datei entfernen und diese Zeile in stdout schreiben.

Dies könnte wirklich alle Nicht-Leerzeichen Daten, aber hier ist die JSON, die ich arbeite mit:

{"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"} 

Antwort

0

Ok, ich glaube, ich habe es, aber wenn jemand jedes Rindfleisch mit dieser Bitte hat das Gefühl, frei kritisieren. Es ist in der Nähe, aber es braucht eine Feinabstimmung, denke ich, es scheint einen Fehler von einem nach dem anderen zu geben oder so ähnlich.

#!/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

Ich wollte gerade eine Antwort mit der Erwähnung von 'fs.createReadStream' posten ... da ich denke, dass du da die richtige Idee hast. Für das Äquivalent zu Pythons Tell gibt es ein paar Möglichkeiten, sich dem zu nähern (zB funktioniert 'fs.readSync' möglicherweise). 'fs.ReadSteam' hat einige Funktionen, mit denen Sie arbeiten können, um das zu tun, was Sie versuchen. –

+0

danke ja, es ist in der Nähe zu arbeiten, aber nicht ganz 100% –

+0

Ich bin mir nicht sicher, ob ich die Position richtig berechne. Ich nehme einfach an, dass die Position die Anzahl der Zeichen in der Datei ist. –

1

Sie sollten am Ende jeder Zeile die Zeilenende-Marke in Betracht ziehen, dass nicht in der ‚Linie‘ enthalten Sie über das Readline- Modul zu bekommen. Das heißt, Sie sollten die Position auf position += (line.length + 1) aktualisieren und dann beim Schreiben einfach position (ohne die -1) verwenden.

+0

danke ich denke, das ist richtig –

+0

irgendeine Idee, was der Unterschied zwischen Bytes (Bytes gelesen) und Position (die Art und Weise haben es berechnet)? In diesem Fall scheint es zu funktionieren, wenn ich die Position gleich der Anzahl der Zeichen in der Datei bis zum Punkt anlege. Aber wenn ich Position gleich der Anzahl der gelesenen Bytes mache, funktioniert es nicht und die Anzahl der gelesenen Bytes ist um einiges größer als die Anzahl der Zeichen, so scheint es. –

+0

Es ist nur eine andere Darstellung der Datenmenge - gelesene Bytes ist die Anzahl der Bytes, die zum Speichern dieser Zeichenfolge verwendet wird, während Position die Anzahl der Zeichen in dieser bestimmten Zeichenfolge darstellt. Sie können diese Datei auch direkt über das fs-Modul des Knotens lesen und mit Bytes arbeiten. Readline ist jedoch ein viel netteres Modul auf höherer Ebene, mit dem Sie für Ihren speziellen Zweck arbeiten können. –

Verwandte Themen