引数とリダイレクトを使うとARGFが使いづらい
ARGFは便利なのですが、挙動にクセがあります。
- 引数がないと、STDINと同等。よって "<" でファイル入力すると、ファイルの内容が展開される。
- 引数があると、引数をファイル名として扱い、そのファイルが展開される。
なので、以下の呼び出しをすると、ARGFは同じ挙動になります。
$> non_arg.rb < list.txt $> non_arg.rb list.txt
一方、引数として何か渡したくなっても、ARGFでファイル名として展開されてしまうので使えません。
というわけで、はじめは楽をしてARGFを使っていたのに引数を与えたくなった・・・というときに、明示的に区別しなければならなくなってしまいましたorz
- 標準入力・・・STDIN
- 引数1・・・ARGV[0]
下は標準入力で入れたファイルリストを指定のディレクトリからコピーしてくるスクリプトです。
参照ディレクトリを引数で変更できるようにしてあります。
#!/usr/bin/ruby require 'fileutils' $KCODE = "EUC" # リストで列挙したファイルを標準入力で取得し、カレントにコピーする # 保存ディレクトリは引数で変更可能。 # ex) xcopy.rb dir1 < list.txt # list.txtは以下の通り # hoge.zip [LR] # ... [LR] $save_dir_head = "/save/" $save_dir_foot = "/files/" if (ARGV[0] == nil) then # Usage puts "command : ./xcopy.rb [target] < [file list]" puts " target :" + `ls /save/`.gsub(/\n/, ", ") exit end $save_dir = $save_dir_head + ARGV[0] + $save_dir_foot if (File.exist?($save_dir) == false) then print "%s is not exist.\n" % [ARGV[0]] exit end STDIN.each{ |filename| file_path = $save_dir + filename.chomp if(File.exist?(file_path) == false) then puts(" %s is not exist." %[file_path]) elsif(File.file?(file_path) == false) then puts(" %s is not a file." %[file_path]) else puts("cp %s" %[filename]) FileUtils.cp(file_path, "./") cmd = "touch -r %s %s " %[file_path, filename] system(cmd) end } print " *** end. ***\n"