Language detail: Batchfile
Coverage: 26.21%
|
number of '+' ratings |
contribution for coverage |
Unsolved challenges
- inline/embeded bytecode assembly (Nested Flatten)
- 疑似並行処理 (Nested Flatten)
- '('と')'の対応 (Nested Flatten)
- 世界時計 (Nested Flatten)
- 漢数字で九九の表 (Nested Flatten)
codes
重複する要素を取り除く
(Nested
Flatten)
バッチで。(内容は #7705とほぼ同様です。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | @echo off
setlocal enabledelayedexpansion
set t=
set v=
set #=0
if "%*" == "" exit /b 1
for %%v in (%*) do (
echo !v! | findstr /l "%%v" > NUL && (set v=!v:%%v=!) || (set v=!v!%%v )
)
for %%v in (%v%) do (
if not defined %%v (
set %%v=!#!
set /a #+=1
)
)
for /f "tokens=1,2 delims==" %%i in ('set ^| findstr /r "^[0-9]"') do set _%%j=%%i
set /a #-=1
for /l %%i in (0,1,%#%) do (
if defined !_%%i! set t=!t!!_%%i!
)
endlocal & if not "%t%" == "" echo %t%
|
アレイのuniq
(Nested
Flatten)
処理的にまずい箇所があったので、一部修正。
15c15
< for /f "tokens=1,2 delims==" %%i in ('set ^| findstr /r "^[0-9]"') do set %%j=%%i
---
> for /f "tokens=1,2 delims==" %%i in ('set ^| findstr /r "^[0-9]"') do set _%%j=%%i
18c18
< for /l %%i in (0,1,%#%) do set t=!t!!%%i!
---
> for /l %%i in (0,1,%#%) do set t=!t!!_%%i!
バッチで。(バッチには配列が無いので、変数で代用しています。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @echo off
setlocal enabledelayedexpansion
set t=
set #=0
if "%*" == "" exit /b 1
for %%v in (%*) do (
if not defined %%v (
set %%v=!#!
set /a #+=1
)
)
for /f "tokens=1,2 delims==" %%i in ('set ^| findstr /r "^[0-9]"') do set %%j=%%i
set /a #-=1
for /l %%i in (0,1,%#%) do set t=!t!!%%i!
endlocal & echo %t%
|
起動オプションの解析
(Nested
Flatten)
以下の書籍を参考にバッチで。 多治見寿和 『プログラミングテクニック』 (アスキー, 2003年, p5)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | @echo off
setlocal enabledelayedexpansion
set #=0
set c=0
set d=
set i=0
set o=0
set p=
set q=0
for %%v in (%*) do (
set p_!#!=%%v
set /a #+=1
)
if %#% equ 0 (call :usage & exit /b 1)
set c=%#%
:_S
if %c% equ 0 goto _E
if not "!p_%i%:~0,1!" == "-" goto _E
:__S
set p=!p_%i%:-=!
if "%p:~0,1%" == "d" (
if !c! equ 1 (call :usage & exit /b 1)
if "%p:~1,1%" == "" (
set /a c-=1,i+=1
for /f "tokens=2 delims==" %%d in ('set p_!i!') do set d=%%d
) else (
set d=%p:~1,1%
)
goto __E
)
if "%p%" == "o" (set o=1) & goto __E
if "%p%" == "q" (set q=1) & goto __E
if "%p%" == "oq" (set o=1) & (set q=1) & goto __E
set /a i+=1
if not "!p_%i%!" == "" goto __S
:__E
set /a c-=1,i+=1
goto _S
:_E
if %o% equ 0 (call :usage & exit /b 1)
if %i% equ %#% (call :usage & exit /b 1)
if not "%d%" == "" echo %d% | findstr /r "[0-2]" > NUL || (call :usage & exit /b 1)
echo.
echo オプション
if %o% equ 1 (echo -o 指定)
if %q% equ 1 (echo -q 指定) else (echo -q 未指定)
if not "%d%" == "" (
echo -d 指定^(値 = %d%^)
) else (
echo -d 未指定
)
echo.
echo パラメータ
for /f "" %%n in ('set /a %#%-%i%') do echo 指定数 = %%n
set /a #-=1
for /l %%i in (%i%,1,%#%) do echo !p_%%i!
endlocal & exit /b 0
goto :EOF
:usage
echo Usage: %~n0 -o [-q] [-d {0^|1^|2}] 文字列 [文字列 ...]
goto :EOF
|
おっと、異常終了とか忘れてた。
バッチファイルの異常終了ってこんなんでいいのかな。
バッチファイルの異常終了ってこんなんでいいのかな。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 46a47,53
>
> set /A COUNT=0
> for %%1 in (%ARGV%) do set /A COUNT += 1
>
> if not "%OPT_O%"=="ON" echo oオプションは必須です。 & exit /b 1
> if "%COUNT%"=="0" echo パラメータは必須です。 & exit /b 1
>
52,54d58
< set /A COUNT=0
< for %%1 in (%ARGV%) do set /A COUNT += 1
<
63a68
> exit /b 0
|
バッチファイル。遅延環境変数展開で。
お題の起動例にあるパターンはすべて解釈できていると思います。
お題の起動例にあるパターンはすべて解釈できていると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | @echo off
setlocal enabledelayedexpansion
set OPT_O=OFF
set OPT_Q=OFF
set ARGV=
set WAIT_OPT_S=0
shift
for %%1 in (%*) do (
call :parse_arg %%1
)
goto parse_end
rem *** パラメータ解析 ***
:parse_arg
set PARA=%1
if "%PARA:~0,1%"=="-" (
set WAIT_OPT_S=0
call :parse_opt %PARA:~1%
) else (
if "%WAIT_OPT_S%"=="1" set OPT_S=%PARA% & set WAIT_OPT_S=0 & goto :EOF
set ARGV=%ARGV% %PARA%
)
goto :EOF
rem *** オプション解析 ***
:parse_opt
set OPT=%1
:parse_an_opt
if "%OPT%"=="" goto :EOF
set OPT2=%OPT:~0,1%
if "%OPT2%"=="o" (
set OPT_O=ON
) else if "%OPT2%"=="q" (
set OPT_Q=ON
) else if "%OPT2%"=="s" (
set OPT_S=%OPT:~1,1%
set OPT=%OPT:~1%
if "!OPT_S!"=="" set WAIT_OPT_S=1
)
set OPT=%OPT:~1%
goto :parse_an_opt
rem *** 結果出力 ***
:parse_end
echo [オプション情報]
echo o : %OPT_O%
echo q : %OPT_Q%
echo s : %OPT_S%
set /A COUNT=0
for %%1 in (%ARGV%) do set /A COUNT += 1
set /A ARGC=1
echo [パラメータ情報]
echo 指定数:%COUNT%
for %%1 in (%ARGV%) do (
echo !ARGC! : %%1
set /A ARGC += 1
)
endlocal
|
LL Golf Hole 6 - 10進数を2進数に基数変換する
(Nested
Flatten)
バッチで。(バッチの制限上、指定できる値は 0から2147483647まで。)
1 2 3 4 5 6 7 8 | @echo off
setlocal
set d=%1
:_
set /a m=d%%2,d/=2
set t=%m%%t%
if %d% gtr 0 goto :_
endlocal & echo %t%
|
LL Golf Hole 7 - バイト数を読みやすくする
(Nested
Flatten)
今日もLLとの彼我兵力差は開きっぱなしですが、バッチで。 バッチで扱える数値の範囲は限られている(0~2147483647)ため、表示可能な単位は Gまで です。また、基本的に整数しか扱えないので、小数点以下 2桁まで求める関数を書いて対 応しました。(値によって若干の誤差が生じる点は目を瞑っています。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | @echo off
setlocal enabledelayedexpansion
set i=0
set n=%1
for %%u in ("" k M G) do (
for /f "delims=." %%i in ("!n!") do set i=%%i
if !i! lss 1024 (echo !n!%%~u & exit /b)
call :div !i! 1024 n
)
endlocal
goto :EOF
:div
setlocal enabledelayedexpansion
set d=
set q=0
set /a n=%1/%2,m=%1%%%2
if %m% gtr 0 (
for /l %%i in (1,1,2) do ( :: 小数点以下 2桁
if !m! gtr 0 (
set /a q=!m!0/%2,m=!m!0%%%2
set d=!d!!q!
)
)
set n=%n%.!d!
)
endlocal & set %3=%n%
goto :EOF
|
LL Golf Hole 8 - 横向きのピラミッドを作る
(Nested
Flatten)
バッチです。
e.g.
C:\>pyramid 4
*
**
***
****
***
**
*
1 2 3 4 5 6 7 8 9 10 11 12 13 | :: pyramid.bat
@echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,%1) do (
set t=!t!*
echo !t!
)
for /l %%i in (%1,-1,2) do (
set t=!t:~1,%%i!
echo !t!
)
endlocal
goto :EOF
|
LL Golf Hole 2 - 文字列に含まれる単語の最初の文字を大文字にする
(Nested
Flatten)
うん、埒外なんだ。(わかっていたけどね... )
e.g.
C:>capitalize "HL day after day"
HL Day After Day
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | :: capitalize.bat
@echo off
setlocal enabledelayedexpansion
set c=
set t=
set w=
if "%~1" equ "" (echo %~n0 [STRING] & exit /b 1)
for %%w in (%~1) do (
set w=%%w
call :upper !w:~0,1! c
set t=!t! !c!!w:~1!
)
endlocal & echo %t:~1%
goto :EOF
:upper
setlocal
set t=%~1
set t=%t:a=A%
set t=%t:b=B%
set t=%t:c=C%
set t=%t:d=D%
set t=%t:e=E%
set t=%t:f=F%
set t=%t:g=G%
set t=%t:h=H%
set t=%t:i=I%
set t=%t:j=J%
set t=%t:k=K%
set t=%t:l=L%
set t=%t:m=M%
set t=%t:n=N%
set t=%t:o=O%
set t=%t:p=P%
set t=%t:q=Q%
set t=%t:r=R%
set t=%t:s=S%
set t=%t:t=T%
set t=%t:u=U%
set t=%t:v=V%
set t=%t:w=W%
set t=%t:x=X%
set t=%t:y=Y%
set t=%t:z=Z%
endlocal & set %2=%t%
goto :EOF
|
tailの実装
(Nested
Flatten)
バッチです。カバレッジ稼ぎのようでちょっと恥ずかしいのですが、あまり処理を複雑に
したくなかったので、標準入力からの入力や-fオプションは実装しませんでした。
e.g.
C:\>tail 3 tail.bat
set /a i-=%1
endlocal & more +%i% %p%
goto :EOF
以下の参考サイトのものはもっと複雑で頭が下がります。
see: 【続々々】tailコマンドの作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | :: tail.bat
@echo off
setlocal
set i=0
set p=%~fs2
echo %1|findstr /r "[^0-9]" >NUL 2>&1
if %ERRORLEVEL% equ 0 (call :usage & exit /b 1)
if "%p%" equ "" (call :usage & exit /b 1)
if not exist %p% (call :usage & exit /b 1)
for /f %%i in ('find /c /v "" ^< %p%') do set i=%%i
set /a i-=%1
endlocal & more +%i% %p%
goto :EOF
:usage
setlocal
echo %~n0 [LINE] [FILE]
endlocal
goto :EOF
|
LL Golf Hole 5 - 最上位の桁を数え上げる
(Nested
Flatten)
#7164をお手本にバッチで。(ワンライナーで76バイトですが、実行速度は遅いです。)
e.g.
C:\>@echo off & (for /l %i in (0,1,300) do echo %i|findstr /r "^.0*$") & echo on
環境変数の取得
(Nested
Flatten)
1 2 3 4 5 6 | rem 環境変数の一覧を表示
set
rem 値の取得
echo USERNAME=[%USERNAME%]
rem ついでに設定
set FOO=bar
|
文字列中のアルファベットを大文字にする
(Nested
Flatten)
バッチで。
e.g.
C:\>upper abc
ABC
遅延環境変数展開を利用しているので、Windows NTでは動作しません。Windows XPで動作
を確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | :: upper.bat
@echo off
setlocal enabledelayedexpansion
set t=
if "%*" equ "" (call :usage & exit /b 1)
for %%s in (%*) do (
call :upper %%s t
echo !t!
)
endlocal & exit /b 0
goto :EOF
:usage
setlocal
echo Usage: %~n0 [STRING...]
endlocal
goto :EOF
:upper
setlocal
set t=%~1
set t=%t:a=A%
set t=%t:b=B%
set t=%t:c=C%
set t=%t:d=D%
set t=%t:e=E%
set t=%t:f=F%
set t=%t:g=G%
set t=%t:h=H%
set t=%t:i=I%
set t=%t:j=J%
set t=%t:k=K%
set t=%t:l=L%
set t=%t:m=M%
set t=%t:n=N%
set t=%t:o=O%
set t=%t:p=P%
set t=%t:q=Q%
set t=%t:r=R%
set t=%t:s=S%
set t=%t:t=T%
set t=%t:u=U%
set t=%t:v=V%
set t=%t:w=W%
set t=%t:x=X%
set t=%t:y=Y%
set t=%t:z=Z%
endlocal & set %2=%t%
goto :EOF
|
変数の初期値
(Nested
Flatten)
バッチでは、if文に defined条件を指定することで変数が定義されているかどうか調べる
ことができます。
使いどころは様々ですが、一例を挙げれば、Windows NTとWindows 2000以降の cmd.exeの
実装の差異を吸収することが可能です。
e.g.
Windows NTの場合
C:\>echo %DATE%
%DATE% <- 環境変数DATEは実装されていないため、変数展開されない。
C:\>date.bat
2008/03/09
Windows 2000の場合
C:\>echo %DATE%
2008/03/09
C:\>date.bat
2008/03/09
1 2 3 4 5 6 7 | :: date.bat
@echo off
setlocal
if not defined DATE for /f %%d in ('date /t') do set DATE=%%d
echo %DATE%
endlocal
goto :EOF
|
最大公約数(除算禁止)
(Nested
Flatten)
バッチは多倍長演算をサポートしていないため、図らずも #4841の「条件(易)」を選択。
除算・余剰については、「除算・余剰を使わずに閏年」で回答したものを流用しました。
e.g.
C:>gcd.bat 1975 1225
25
遅延環境変数展開を利用しているので、Windows NTでは動作しません。Windows XPで動作
を確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | :: gcd.bat
@echo off
setlocal
set n=0
echo %1%2|findstr /r "[^0-9]" >NUL 2>&1
if %ERRORLEVEL% equ 0 (echo %~n0 [NUMBER] [NUMBER]) & goto :EOF
call :gcd %1 %2 n
endlocal & echo %n%
goto :EOF
:gcd
setlocal enabledelayedexpansion
set a=%1
set b=%2
set m=0
set q=0
if %a% lss %b% (
set /a a=%b%-%a%
set /a b-=!a!
set /a a+=!b!
)
:loop_gcd
call :mod %a% %b% m
if %m% equ 0 (endlocal & set %3=%b%) & goto :EOF
:: 剰余を除数の半分未満にして演算効率を向上
call :div %b% 2 q
if %q% lss %m% set /a m=%b%-%m%
set a=%b%
set b=%m%
goto loop_gcd
endlocal
goto :EOF
:mod
setlocal
set m=0
set q=0
call :div %1 %2 q
set /a m=%2*%q%
endlocal & set /a %3=%1-%m%
goto :EOF
:div
setlocal enabledelayedexpansion
set i=0
set m=%1
set m_=0
set n=%2
set n_=0
set q=0
if %n% gtr %m% (endlocal & set %3=%q%) & goto :EOF
call :msb %m% m_
call :msb %n% n_
set /a i=%m_%-%n_%
:loop_div
if %i% lss 0 (endlocal & set %3=%q%) & goto :EOF
set /a "q<<=1"
set /a "m_=%m%>>%i%"
if %m_% geq %n% (
set /a "n_=%n%<<%i%"
set /a m-=!n_!
set /a q+=1
)
set /a i-=1
goto loop_div
endlocal
goto :EOF
:: 最上位ビットを取得(most significant bit)
:msb
setlocal
set i=%1
set n=0
:loop_msb
set /a "i>>=1"
set /a n+=1
if %i% neq 0 goto loop_msb
endlocal & set %2=%n%
goto :EOF
|
除算・余剰を使わずに閏年
(Nested
Flatten)
ビット演算を利用して除算を実装しました。(ちなみに、紀元前には対応していません。)
e.g.
C:>@echo off & (for %y in (1000 2000 2008) do is_leap_year %y) & echo on
1000年は平年です。
2000年は閏年です。
2008年は閏年です。
遅延環境変数展開を利用しているので、Windows NTでは動作しません。Windows XPで動作
を確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | :: is_leap_year.bat
@echo off
setlocal
set l=0
set s=平年
echo %1|findstr /r "[^0-9\-]" >NUL 2>&1
if %ERRORLEVEL% equ 0 (echo %~n0 [YEAR] & goto :EOF)
call :L %1 l
if %l% equ 1 set s=閏年
endlocal & echo %1年は%s%です。
goto :EOF
:L
setlocal
set m=0
call :mod %1 400 m
if %m% equ 0 endlocal & set %2=1 & goto :EOF
call :mod %1 100 m
if %m% equ 0 endlocal & set %2=0 & goto :EOF
call :mod %1 4 m
if %m% equ 0 endlocal & set %2=1 & goto :EOF
goto :EOF
:mod
setlocal
set m=0
set q=0
call :div %1 %2 q
set /a m=%2*%q%
endlocal & set /a %3=%1-%m%
goto :EOF
:div
setlocal enabledelayedexpansion
set i=0
set m=%1
set m_=0
set n=%2
set n_=0
set q=0
if %n% gtr %m% endlocal & set %3=%q% & goto :EOF
call :msb %m% m_
call :msb %n% n_
set /a i=%m_%-%n_%
:loop_div
if %i% lss 0 endlocal & set %3=%q% & goto :EOF
set /a "q<<=1"
set /a "m_=%m%>>%i%"
if %m_% geq %n% (
set /a "n_=%n%<<%i%"
set /a m-=!n_!
set /a q+=1
)
set /a i-=1
goto loop_div
endlocal
goto :EOF
:: 最上位ビットを取得(most significant bit)
:msb
setlocal
set i=%1
set n=0
:loop_msb
set /a "i>>=1"
set /a n+=1
if %i% neq 0 goto loop_msb
endlocal & set %2=%n%
goto :EOF
|
ファイル更新の監視
(Nested
Flatten)
指定されたファイルのコピーを一時ディレクトリ(%TEMP%)に作成し、バイナリモードで元
のファイルと比較しています。タイムスタンプだけが更新された場合には検出できません。
e.g.
C:>monitor monitor.bat
指定されたファイルを監視しています。
終了するにはCtrl-Cを押してください。
02:22:22 指定されたファイルが更新されました。
Windows XPで動作を確認。fcはWindows NTにも存在するので、NTでも動作するかもしれま
せん。
# 为了妈贡献出我自己手里的全部二。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | :: monitor.bat
@echo off
setlocal
set f=%TEMP%\%~nx1
if "%1" == "" (echo %~n0 [FILE] & goto :EOF)
if not exist %1 (echo 指定されたファイルが見つかりません。 & goto :EOF)
echo 指定されたファイルを監視しています。
echo 終了するにはCtrl-Cを押してください。
echo.
copy %1 %f% >NUL
:loop
fc /b %f% %1 >NUL
if %ERRORLEVEL% equ 1 (
for /f "tokens=2 delims=. " %%t in ('echo.^|time') do echo %%t 指定されたファイルが更新されました。
copy %1 %f% >NUL
)
ping -n %1 127.0.0.1 >NUL
goto loop
endlocal
goto :EOF
|
自分自身のファイル名を知る方法
(Nested
Flatten)
next >>
#3301は拡張子を含まない例なので、拡張子を含むファイル名を取得する方法を検証しま
した。なお、「長いファイル名」とは「ロングファイルネーム( LFN)」のことを、「短い
ファイル名」とはいわゆる「 8.3形式( SFN)」のことを指していると思ってください。
e.g.
C:\>"C:\Documents and Settings\kshibamo\デスクトップ\どう書く?org Beta.bat"
長いファイル名 : どう書く?org Beta.bat
短いファイル名 : どう書~1.BAT
Windows NT, 2000, XP, 2003で動作確認したところ、パス文字列にマルチバイトが含まれ
る場合に限り、Windows NTと2000では短いファイル名を取得することができませんでした。
e.g.
Windows NTの場合
短いファイル名 : org Beta
Windows 2000の場合
短いファイル名 : (何も出力されない)
1 2 3 4 5 6 7 | :: どう書く?org Beta.bat
@echo off
setlocal
echo 長いファイル名 : %~nx0
echo 短いファイル名 : %~nxs0
endlocal
goto :EOF
|






silverwire
#7750()
[
Batchfile
]
Rating0/0=0.00
@echo off setlocal enabledelayedexpansion set a=0 set d=0 set l=0 set z= if "%1" == "" (echo %~n0 [FILE] & exit /b 1) for /f "tokens=1-4" %%a in (%1) do ( echo %%a %%c %%b %%d goto _BREAK_ ) :_BREAK_ for /f "tokens=1" %%a in ('more +1 %1') do ( if %%a gtr !a! set a=%%a ) call :length %a% l for /l %%i in (1,1,%l%) do set z=!z!0 for /f "tokens=1-4" %%a in ('more +1 %1') do ( set a=%z%%%a set /a d=%%d+1 set %~n0_!a:~-%l%!=%%a %%c %%b !d! ) for /f "tokens=2 delims==" %%l in ('set %~n0_') do echo %%l endlocal goto :EOF :length setlocal set i=0 set t=%~1 if "%t%" == "" endlocal & set %2=0 :_LENGTH_ set t=%t:~1% set /a i+=1 if not "%t%" == "" goto _LENGTH_ endlocal & set %2=%i% goto :EOFRating0/0=0.00-0+
[ reply ]