やりたいこと
ターミナルのls -l
コマンドの結果を自分で作ったwcコマンドにかけて行数・単語数・容量を表示させたい。
つまり以下の処理をしたい。
ls -l | wc
コード
# 標準入力を受け取る input = $stdin.read # 行数を取得 def load_lines(str) str.count("\n") end # 単語数を取得 def load_words(str) str.split(/\s/).reject(&:empty?).size end # バイト数を取得 def load_bytes(str) str.bytesize end def all_data(input) lines = load_lines(input) # 行数 words = load_words(input) # 単語数 bytes = load_bytes(input) # バイト数 print lines.to_s.rjust(8) print words.to_s.rjust(8) print bytes.to_s.rjust(8) puts end all_data(input)
説明
wcコマンドは、オプションなしだと「行数・単語数・容量(バイト数)」の順で表示する。
標準入力を受け取る
input = $stdin.read
これで標準入力を読み込み、文字列でinputに保存する。 文字列で取得するのがポイント。
行数
wcコマンドは行数というより、改行文字の数を数える仕様になっている。よって、改行文字である\n
を数えてやればよい。
def load_lines(str) str.count("\n") end
単語数
wcコマンドの単語数の定義は、空白や改行文字で区切った単語のこと。
def load_words(str) str.split(/\s/).reject(&:empty?).size end
取得した文字列をsplitメソッドにかけ、\s+
で区切って配列に入れる。\s
は空白を意味する。
空文字列があったらいけないので、.reject(&:empty?)
で要素がエンプティ(空)だったら削除。
その後、sizeメソッドで要素数、つまり単語数を数える。
容量(バイト数)
def load_bytes(str) str.bytesize end
bytesizeメソッドで容量(バイト数)をカウントできる。
表示
print lines.to_s.rjust(8) print words.to_s.rjust(8) print bytes.to_s.rjust(8)
最後に、wcコマンドの表示方式に合わせる。
ls -l | wc 7 56 398
これは右に寄せているので、rjust
メソッドが使えそう。
ただし、各メソッドの戻り値は数値のため、rjustメソッドは使えない。stringオブジェクトにしか使えないからだ。
そこで、to_s
メソッドでstringオブジェクトに変換する。
結果
ls -l | wc 7 56 398
ls -l | ruby input.rb 7 56 398
どちらも同じ結果になった。