Read a gzipped file eventually from STDIN: what is the correct way?

Viewed 98

I'd like to be able to read from a text file that can be gzipped and can come as a stream from stdin.

import zip/gzipfiles  # Import zip package
# get "inputFile" being a string with the filename or "-" to read from STDIN?
if inputFile == "-":
  inputFile = "/dev/stdin"
let file = newGzFileStream(inputFile)
  defer: file.close()
  var line: string  # Declare line variable
  while not file.atEnd():
    line = file.readLine()
    echo line

The way I implemented it cat file.txt(.gz) | my_prog results in checking the first argument, if not supplied, or if equal to "-", the program sets inputFile to "/dev/stdin".

I don't know if this is a correct way, and can be ported from one POSIX system to another, for example, or if there's a "proper" way (I'd like to have better words to formulate the question).

1 Answers

Check out https://scripter.co/nim-check-if-stdin-stdout-are-associated-with-terminal-or-pipe/#stdin-stdout-isatty

Pasting the code here for completeness:

# Figuring out if input is coming from a pipe and if output is going to a pipe.
import std/[terminal, strutils]

if isatty(stdin):
  # ./stdin_stdout foo
  # ./stdin_stdout foo | cat
  echo "--> Input from terminal"
else:
  # echo bar | ./stdin_stdout
  # echo bar | ./stdin_stdout | cat
  echo "--> Input from a PIPE/FILE: `" & readAll(stdin).strip() & "'"

if isatty(stdout):
  # ./stdin_stdout foo
  # echo bar | ./stdin_stdout foo
  echo "    Output to terminal -->"
else:
  # ./stdin_stdout | cat
  # echo bar | ./stdin_stdout | cat
  echo "    Output to a PIPE -->"

Another example

import std/[terminal, strutils, os]

# Assuming space-separated file names.
let
  inputFiles = if isatty(stdin):
                 commandLineParams()
               else:
                 readAll(stdin).strip().split()
echo "inputFiles = ", inputFiles

With above code, we get this outcome:

> ./BINARY abc.txt def.txt
inputFiles = @["abc.txt", "def.txt"]

> echo "abc.txt def.txt" | ./BINARY
inputFiles = @["abc.txt", "def.txt"]

> echo "abc.txt\n def.txt" | ./BINARY
inputFiles = @["abc.txt", "def.txt"]
Related