0

So I need to use an input file in my terminal, and when I write the following cat input.txt | node prog.js >result.txt

My code is :

var fs = require('fs');
var str = fs.readFileSync('input.txt', 'utf8');

str.replace(/^\s*[\r\n]/gm,"").split(/\s+/).forEach(function (s) {
    return console.log(
    s === 'bob'
        ? 'boy'
        : s === 'alicia'
        ? 'girl'
        : s === 'cookie'
        ? 'dog'
        : 'unknown');
});

I need my code to take an input document regardless of the name the user may give it. What is the correct way to grab user input?

3 Answers 3

2

if you pipe out a value to a node.js script you have to listen to the readable or data event listener available to the process object. Using the data event listener places the stream straight into flowing mode, whenever you use the readable event listener you have to force stdin to flowing mode using process.stdin.read(). To write to another command or to another script you have to use process.stdout.write(), it's a writeable stream.

Flowing mode

#!/usr/bin/env node

let chunks = "";

process.stdin.on("data", data => {
    // data is an instance of the Buffer object, we have to convert it to a string
    chunks += data.toString();
})

// the end event listener is triggered whenever there is no more data to read

process.stdin.on("end", () => {
    // pipe out the data to another command or write to a file
    process.stdout.write(chunks);
});

Non Flowing mode

#!/usr/bin/env node

process.stdin.on("readable", () => {
    const flowingMode = process.stdin.read();
    // flowingMode will become null, whenever there is no more data to read
    if ( flowingMode )
        chunks += flowingMode.toString();
})

process.stdin.on("end", () => {
    process.stdout.write(chunks);   
})

To prevent your self all this stress, you can do something like the below if there is non logic on the readable or data event handler

#!/usr/bin/env node

process.stdin.pipe(process.stdout);

if you want to do something whenever the end event listener is triggered you should do this

#!/usr/bin/env node

process.stdin.pipe(process.stdout, { end: false } );

process.stdin.on("end", () => /* logic */ );

when the end event listener is triggered execute your code

#!/usr/bin/env node

let chunk = "";

process.stdin.on("data", data => {
    chunk += data.toString();
});

process.stdin.on("end", () => {
    chunk.replace(/^\s*[\r\n]/gm,"").split(/\s+/).forEach(function (s) {
        process.stdout.write(
        s === 'bob'
        ? 'boy'
        : s === 'alicia'
           ? 'girl'
           : s === 'cookie'
               ? 'dog'
               : 'unknown');
    });
});

> cat input.txt | ./prog.js > result.txt
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for you answer, but sorry I don't understand how can I mix it with my code?
That is not the question you asked
I am so sorry my question was not clear, it's my fault. For me the goal it's to use the following command I put in my post, and I don't know how can I code in JS in order to use the command. Because we can change the name of the following input "input.txt", and I want a code which take any file name enters in commade in the terminal
Thank you for your answer @0.sh
1

Piping something into a Node script does require you to read from process.stdin, as @T.J.Crowder mentions.

Have a look at this article, which explains the idea, with a good example to follow: https://blog.rapid7.com/2015/10/20/unleash-the-power-of-node-js-for-shell-scripting-part-1/ e.g.:

#!/usr/bin/env node 
const readInput = callback => {
  let input = '';
  process.stdin.setEncoding('utf8');
  process.stdin.on('readable', () => {
      const chunk = process.stdin.read();
      if (chunk !== null) {
          input += chunk;
      }
  });
  process.stdin.on('end', () => callback(input));
}
readInput(console.log);

Comments

0

What you're asking is "How do I read from standard input?" The answer is to use process.stdin, which is a Stream.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.