নোডের লাইনে বাই স্টিডিন থেকে কীভাবে পড়বেন


177

আমি কোনও কমান্ড লাইন কল ব্যবহার করে নোড সহ একটি পাঠ্য ফাইল প্রসেস করতে চাই:

node app.js < input.txt

ফাইলের প্রতিটি লাইন পৃথকভাবে প্রক্রিয়া করা প্রয়োজন, তবে একবার প্রক্রিয়া করা ইনপুট লাইনটি ভুলে যেতে পারে।

স্টিডিনের অন-ডেটা শ্রোতাদের ব্যবহার করে, আমি ইনপুট স্টিমটি বাইট আকারের দ্বারা ছাঁটাই করি তাই আমি এটি সেট আপ করি।

process.stdin.resume();
process.stdin.setEncoding('utf8');

var lingeringLine = "";

process.stdin.on('data', function(chunk) {
    lines = chunk.split("\n");

    lines[0] = lingeringLine + lines[0];
    lingeringLine = lines.pop();

    lines.forEach(processLine);
});

process.stdin.on('end', function() {
    processLine(lingeringLine);
});

তবে এটি এতটা নিচু মনে হচ্ছে। লাইন অ্যারের প্রথম এবং শেষ আইটেমের চারপাশে ম্যাসেজ করা। এটি করার জন্য আরও মার্জিত উপায় নেই?

উত্তর:


207

স্টিডিন লাইন থেকে রেখার মাধ্যমে পড়তে আপনি পঠন মডিউলটি ব্যবহার করতে পারেন :

var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

rl.on('line', function(line){
    console.log(line);
})

3
এটি কনসোলে হাত দ্বারা ইনপুট প্রবেশের জন্য ভাল কাজ করছে বলে মনে হচ্ছে, যাইহোক, আমি যখন কোনও ফাইল কমান্ডটিতে পাস করি তখন ফাইলটি স্টাডআউটে প্রেরণ করা হয়। একটি বাগ? পাঠ্যলাইন এই মুহূর্তে অস্থির হিসাবে বিবেচিত হয়।
ম্যাট আর। উইলসন

1
আমি মনে করি আপনি কেবল process.stdoutএকটি অন্য লিখনযোগ্য স্ট্রিমে পরিবর্তন করতে পারবেন - এটি output: new require('stream').Writable()
এতটা

3
দুর্ভাগ্যক্রমে, আমার stdout প্রয়োজন। আমি এটিকে আমার প্রশ্ন থেকে দূরে রেখেছি, তবে আমি চেষ্টা করছি অ্যাপটি যাতে ব্যবহারযোগ্য হয় node app.js < input.txt > output.txt
ম্যাট আর। উইলসন

স্পষ্টতই এটি 'ডিজাইনের মাধ্যমে' github.com/joyent/node/issues/4243#issuecomment-10133900 । সুতরাং আমি যেমনটি বলেছিলাম তেমনই শেষ করেছি এবং আউটপুট বিকল্পটি একটি ডামি লিখনযোগ্য স্ট্রিম সরবরাহ করেছিলাম, তারপরে সরাসরি স্টডআউট স্ট্রিমে লিখেছিলাম। আমি এটি পছন্দ করি না, তবে এটি কাজ করে।
ম্যাট আর। উইলসন

13
দেখে মনে হচ্ছে আপনি যদি যুক্তিটি terminal: falseতৈরির ইন্টারফেসে পাস করেন তবে এটি এই সমস্যার সমাধান করে।
জেসনক্রাফোর্ড

61
// Work on POSIX and Windows
var fs = require("fs");
var stdinBuffer = fs.readFileSync(0); // STDIN_FILENO = 0
console.log(stdinBuffer.toString());

3
আপনি কিছু বিবরণ অন্তর্ভুক্ত করতে পারেন? ইতিমধ্যে একটি উচ্চ রেটযুক্ত গৃহীত উত্তর রয়েছে
jhhoff02

2
এটি আমার পক্ষে কাজ করে না (নোড ভি 9.2.0, উইন্ডোজ)। Error: EISDIR: illegal operation on a directory, fstat at ট্রাইস্ট্যাট সিঙ্ক (fs.js: 534: 13) `
অ্যালেক্সচ্যাফি

2
ওএসএক্স নোড v6.11.2 এ আমার জন্য কাজ করেছেন।
টিফন

3
@ অ্যালেক্সচাফি: উইন্ডোজে কোনও বাগ রয়েছে বলে মনে হচ্ছে (এখনও v9.10.1 অনুসারে উপস্থিত রয়েছে) যদি স্টিডিন ইনপুট না থাকে বা স্টিডিন বন্ধ থাকে - এই গিটহাবের সমস্যাটি দেখুন । এছাড়াও এই, তবে সমাধান আছে কাজ Windows এ।
mklement0

3
খুব ভাল কাজ করে এবং এখন পর্যন্ত সংক্ষিপ্ততম, এটি করে আরও সংক্ষিপ্ত করে তুলতে পারেfs.readFileSync(0).toString()
লোকালহোস্টডটদেব

56

readlineটার্মিনাল (যা হয় process.stdin.isTTY === true) এর সাথে কাজ করার জন্য বিশেষভাবে ডিজাইন করা হয়েছে । সেখানে মডিউল যা জেনেরিক স্ট্রিম জন্য বিভক্ত কার্যকারিতা প্রদান, মত অনেক আছে বিভক্ত । এটি জিনিসগুলিকে অতি-সহজ করে তুলেছে:

process.stdin.pipe(require('split')()).on('data', processLine)

function processLine (line) {
  console.log(line + '!')
}

6
না এইটা না. আপনি যদি লাইন বাই লাইন পড়তে না চান তবে আপনার একেবারেই প্রয়োজন হবে না
ভুকরচ্যাটকিন

6
টিপ: আপনি যদি সমস্ত লাইন প্রক্রিয়াজাত করার পরে কিছু কোড চালাতে চান .on('end', doMoreStuff)তবে প্রথমটির পরে যুক্ত করুন .on()। মনে রাখবেন যে আপনি যদি বিবৃতি দিয়ে কেবল কোডটি সাধারণত লিখে থাকেন তবে .on()যে কোনও ইনপুট পড়ার আগে সেই কোডটি চলবে, কারণ জাভাস্ক্রিপ্ট সিঙ্ক্রোনাস নয়।
ররি ও'কেনে

14
#!/usr/bin/env node

const EventEmitter = require('events');

function stdinLineByLine() {
  const stdin = new EventEmitter();
  let buff = "";

  process.stdin
    .on('data', data => {
      buff += data;
      lines = buff.split(/[\r\n|\n]/);
      buff = lines.pop();
      lines.forEach(line => stdin.emit('line', line));
    })
    .on('end', () => {
      if (buff.length > 0) stdin.emit('line', buff);
    });

  return stdin;
}

const stdin = stdinLineByLine();
stdin.on('line', console.log);

0

অন্যদের জন্য ভাগ:

লাইনে স্ট্রিম লাইন পড়ুন, স্টিডিনে পাইপযুক্ত বড় ফাইলগুলির জন্য ভাল হওয়া উচিত, আমার সংস্করণ:

var n=0;
function on_line(line,cb)
{
    ////one each line
    console.log(n++,"line ",line);
    return cb();
    ////end of one each line
}

var fs = require('fs');
var readStream = fs.createReadStream('all_titles.txt');
//var readStream = process.stdin;
readStream.pause();
readStream.setEncoding('utf8');

var buffer=[];
readStream.on('data', (chunk) => {
    const newlines=/[\r\n]+/;
    var lines=chunk.split(newlines)
    if(lines.length==1)
    {
        buffer.push(lines[0]);
        return;
    }   

    buffer.push(lines[0]);
    var str=buffer.join('');
    buffer.length=0;
    readStream.pause();

    on_line(str,()=>{
        var i=1,l=lines.length-1;
        i--;
        function while_next()
        {
            i++;
            if(i<l)
            {
                return on_line(lines[i],while_next);
            }
            else
            {
                buffer.push(lines.pop());
                lines.length=0;
                return readStream.resume();
            }
        }
        while_next();
    });
  }).on('end', ()=>{
      if(buffer.length)
          var str=buffer.join('');
          buffer.length=0;
        on_line(str,()=>{
            ////after end
            console.error('done')
            ////end after end
        });
  });
readStream.resume();

-1

আমার ক্ষেত্রে প্রোগ্রাম (এলিংকস) খালি দেখায় এমন লাইনগুলি ফিরিয়েছিল তবে বাস্তবে বিশেষ টার্মিনাল অক্ষর, রঙ নিয়ন্ত্রণ কোড এবং ব্যাকস্পেস ছিল, সুতরাং grepঅন্যান্য উত্তরে উপস্থাপন করা বিকল্পগুলি আমার পক্ষে কার্যকর হয়নি। তাই আমি এই ছোট স্ক্রিপ্টটি নোড.জেজে লিখেছি। আমি ফাইলটি কল করেছি tight, তবে এটি কেবল একটি এলোমেলো নাম।

#!/usr/bin/env node

function visible(a) {
    var R  =  ''
    for (var i = 0; i < a.length; i++) {
        if (a[i] == '\b') {  R -= 1; continue; }  
        if (a[i] == '\u001b') {
            while (a[i] != 'm' && i < a.length) i++
            if (a[i] == undefined) break
        }
        else R += a[i]
    }
    return  R
}

function empty(a) {
    a = visible(a)
    for (var i = 0; i < a.length; i++) {
        if (a[i] != ' ') return false
    }
    return  true
}

var readline = require('readline')
var rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false })

rl.on('line', function(line) {
    if (!empty(line)) console.log(line) 
})
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.