1

I need to pass a text file as an argument instead of opening it inside the code. The content of the text file should print on console. I have done the following code:

File.open("test_list.txt").each do |line|
    puts line
end

Please advice.

sawa
  • 165,429
  • 45
  • 277
  • 381
Sam
  • 77
  • 2
  • 8
  • Do you mean you wish to pass a string that is the contents of the file? If so, and `s` is that string, just `puts s`. – Cary Swoveland Apr 16 '18 at 02:26
  • Your question is really unclear. Do you want to read a file's content from `stdin` and print each line of that or do you want to read the file name and open that and print it? – dawg Apr 16 '18 at 02:29
  • I need to pass test_list.txt as an argument and if i run following code in console it should print contents of the text file, cat test_list.txt | ruby foo.rb – Sam Apr 16 '18 at 02:45

2 Answers2

5

On your shell, invoke the ruby script followed by the name of the .txt file, like this:

ruby foo.rb test_list.txt

The variable ARGV will contain references to all the arguments you've passed when invoking the ruby interpreter. In particular, ARGV[0] = "test_list.txt", so you can use this instead of hardcoding the name of the file:

File.open(ARGV[0]).each do |line|
    puts line
end



On the other hand, if you want to pass the content of the file to your program, you can go with:

cat test_list.txt | ruby foo.rb

and in the program:

STDIN.each_line do |line|
    puts line
end
Daniele Cappuccio
  • 1,952
  • 2
  • 16
  • 31
1

Ruby has Perl / awk / sed roots. Like Perl and awk, you can use the 'magic' of either reading stdin or opening a file name if that is supplied on the command line with the same code.

Given:

$ cat file
line 1
line 2
line 3

You can write a cat like utility that will open a named file:

$ ruby -lne 'puts $_' file
line 1
line 2
line 3

Or, same code, will read stdin line by line:

$ cat file | ruby -lne 'puts $_'
line 1
line 2
line 3

In this particular case, it is from the -lne command line arguments to Ruby.

 -n             Causes Ruby to assume the following loop around your
                script, which makes it iterate over file name arguments
                somewhat like sed -n or awk.

                      while gets
                        ...
                      end

 -l             (The lowercase letter ``ell''.)  Enables automatic line-
                ending processing, which means to firstly set $\ to the
                value of $/, and secondly chops every line read using
                chop!.

 -e command     Specifies script from command-line while telling Ruby not
                to search the rest of the arguments for a script file
                name.

You can also do:

$ ruby -pe '' file 
# same

Without using the -n switch, you can also use the ARGF stream and modify your code so that it will either use stdin or a named file in the same way.

Named file:

$ ruby -e '$<.each_line do |line|
    puts line
end' file
line 1
line 2
line 3

Read stdin with same code:

$ cat file | ruby -e '$<.each_line do |line|
    puts line
end' 
line 1
line 2
line 3

Or open the file named as a command line argument:

ruby -e 'ARGV.each{|arg| 
    puts "\"#{File.expand_path(arg)}\" contains:"
    puts File.open(arg).read
}
' file 
"/tmp/file" contains:
line 1
line 2
line 3
dawg
  • 98,345
  • 23
  • 131
  • 206