読者です 読者をやめる 読者になる 読者になる

あーるPG - 社会人のデジタル生活

日曜プログラマになろうかなーと思った30代理系社会人の、キャリアアップや趣味(特にデジタル情報)の記録。らーめんとビールが好き。

引数とリダイレクトを使うと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"
広告を非表示にする