LoginSignup
1
0

More than 5 years have passed since last update.

seq コマンド for windows

Posted at

wc コマンドに引き続き、また作りました。

例によって例のとおりです。

' 名前
'     seq - 単調増加 (減少) する数値列を表示する
' 
' 書式
'     seq [/w] [/s SEP] [/equal-width] [/separator SEP] <LAST | FIRST LAST | FIRST INCR LAST>
' 
'     seq [/?] [/help] [/v] [/version]
' 
' 説明
'     seq は FIRST から LAST まで、INCR ずつ加えた数値を表示する。 
'     LAST または INCR が省略された場合、デフォルトは 1 になる。
' 
' オプション
'     /s SEP, /separator SEP
'         数値を SEP で区切る。(デフォルト: ‘\n’)
' 
'     /w, /equal-width
'         桁数を揃えるために (先頭を) 0 で埋める。
' 
'     /?, /help
'         使用法のメッセージを標準出力に表示し、正常終了する。
' 
'     /v, /version
'         バージョン情報を標準出力に表示し、正常終了する。
' 
' 注意
'     小数値は正確に計算できない。
' ==============================================================================
option explicit

' ==========
' parameters
' ==========
dim sep, width
sep = Chr(10)
width = false


' ========================
' parse arguments(options)
' ========================
dim arg, i
do while i < WScript.Arguments.Count
    arg = WScript.Arguments.Item(i)
    if Left(arg, 1) <> "/" then exit do

    select case arg
    'case "/f", "/format"
    case "/s", "/separator"
        i = i + 1
        if i >= WScript.Arguments.Count then call WScript.Quit(1)
        sep = WScript.Arguments.Item(i)
    case "/w", "/equal-width"
        width = true
    case "/?", "/help"
        call WScript.Echo("単調増加 (減少) する数値列を表示する")
        call WScript.Echo("Usage: seq [/w] [/s SEP] [/equal-width] [/separator SEP] <LAST | FIRST LAST | FIRST INCR LAST>")
        call WScript.Echo("Usage: seq [/?] [/help] [/v] [/version]")
        call WScript.Quit(0)
    case "/v", "/version"
        call WScript.Echo("seq version 0.1")
        call WScript.Quit(0)
    end select
    i = i + 1
loop


' ==================================
' parse arguments(first, last, incr)
' ==================================
dim first, incr, last
first = 1
incr = 1
last = 1
select case WScript.Arguments.Count - i
case 1
    last = WScript.Arguments.Item(i)
case 2
    first = WScript.Arguments.Item(i)
    last = WScript.Arguments.Item(i + 1)
case 3
    first = WScript.Arguments.Item(i)
    incr = WScript.Arguments.Item(i + 1)
    last = WScript.Arguments.Item(i + 2)
case else
    call WScript.StdErr.WriteLine("seq: missing operand")
    call WScript.StdErr.WriteLine("seq /? を実行してください")
    call WScript.Quit(1)
end select


' ==========
' calc width
' ==========
dim inte, deci
inte = max(len_inte(first), len_inte(incr), len_inte(last)) ' largest integer part length
deci = max(len_deci(first), len_deci(incr), len_deci(last)) ' largest decimal part length


' ====================
' arguments error trap
' ====================
on error resume next
first = cdbl(first)
if err.number <> 0 then call WScript.StdErr.WriteLine("seq: invalid number argument: " & first): call WScript.Quit(1)

last = cdbl(last)
if err.number <> 0 then call WScript.StdErr.WriteLine("seq: invalid number argument: " & last): call WScript.Quit(1)

incr = cdbl(incr)
if err.number <> 0 then call WScript.StdErr.WriteLine("seq: invalid number argument: " & incr): call WScript.Quit(1)
on error goto 0

if cdbl(incr) = 0 then call WScript.Quit(1)
if cdbl(first) > cdbl(last) and cdbl(incr) > 0 then call WScript.Quit(1)
if cdbl(first) < cdbl(last) and cdbl(incr) < 0 then call WScript.Quit(1)


' ===============
' output sequence
' ===============
dim distance, progress, stdout
set stdout = WScript.Stdout
i = first
distance = abs(last - first)
progress = 0 ' 進捗ダメです><
do while progress <= distance
    if width then
        call printf(cstr(i), inte, deci)
    else
        call stdout.Write(i)
    end if
    call stdout.Write(sep)
    i = round(i + incr, deci)
    progress = abs(first - i)
loop


' ================
' define functions
' ================
function max(byval a, byval b, byval c)
    max = a
    if max < b then max = b
    if max < c then max = c
end function

function len_inte(byval strnum)
    dim point
    point = inStr(strnum, ".")
    if point > 0 then
        len_inte = point - 1
    else
        len_inte = len(strnum)
    end if
end function

function len_deci(byval strnum)
    dim point
    point = inStr(strnum, ".")
    if point > 0 then
        len_deci = len(strnum) - point
    else
        len_deci = 0
    end if
end function

function printf(byval num, byval inte_length, byval deci_length)
    dim sign, inte, deci
    sign = 1
    inte = fix(num)
    deci = round(num - inte, deci_length)

    if num < 0 then sign = -1: inte = -inte

    dim stdout
    set stdout = WScript.Stdout
    if sign < 0 then
        call stdout.Write("-")
        call stdout.Write(lpad(cstr(inte), inte_length - 1))
    else
        call stdout.Write(lpad(cstr(inte), inte_length))
    end if

    if deci <> 0 then
        call stdout.Write(".")
        call stdout.Write(rpad(mid(abs(cstr(deci)), 3), deci_length))
    elseif deci_length > 0 then
        call stdout.Write(".")
        call stdout.Write(rpad("0", deci_length))
    end if
end function

function lpad(byval str, byval length)
    lpad = str
    do while len(lpad) < length
        lpad = "0" & lpad
    loop
end function

function rpad(byval str, byval length)
    rpad = str
    do while len(rpad) < length
        rpad = rpad & "0"
    loop
end function
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0