シェル芸(マウスをつかわず、ソースコードものこさず、 GUI ツールを立ちあげる間もなく、あらゆる調査・計算・テキスト処理を CLI 端末へのコマンド入力一撃で終わらす)の勉強会で出題された問題をバッチファイルで解いてみました。
上田ブログ
http://blog.ueda.asia/?p=1955
2014-02-15.bat
@echo off
set SELF=%~n0
set HELP=Usage: %SELF% NUMBER
set HOME=%~dps0
set HOME=%HOME:~0,-1%
setlocal enabledelayedexpansion
:: 位置パラメーターを確認
if "%~1" == "" (
echo %HELP% >&2
exit /b 1
)
:: 値が数値か確認
(echo %~1) | findstr /r "[^0-9]." > NUL
if %ERRORLEVEL% equ 0 (
echo %HELP% >&2
exit /b 1
)
:: 位置パラメーターを取得
set n=%~1
:: 値が範囲内か確認(Q1からQ8まで)
if %n% lss 1 (
echo %SELF%: illegal value: use 1-8 >&2
exit /b 1
)
if %n% gtr 8 (
echo %SELF%: illegal value: use 1-8 >&2
exit /b 1
)
:: 作業フォルダーを作成
set CWD=%HOME%\A%n%
md %CWD%
:: テストを実行
call :A%n% %CWD%
if %ERRORLEVEL% neq 0 (
echo %SELF%: script abended: A%n% >&2
exit /b 1
)
:: 作業フォルダーを削除
cd %CWD%\..
rd /s /q %CWD%
endlocal
goto :EOF
:A1
setlocal enabledelayedexpansion
set CWD=%~1
:: ファイルを作成
for %%f in (apple avocado banana cinnamon melon) do (
copy NUL %CWD%\%%f > NUL
)
:: フォルダーを作成
for %%d in (a b c m) do (
md %CWD%\%%d
)
:: ファイルをフォルダーに移動
for %%f in (%CWD%\*) do (
set t=%%~nxf
move %CWD%\!t! %CWD%\!t:~0,1!
)
:: 結果を表示
echo.
tree /f %CWD%
endlocal
goto :EOF
:A2
setlocal enabledelayedexpansion
set CWD=%~1
:: ファイルを作成
for %%f in ("私は 蟹" "オシャレな 蟹" "足が 10本") do (
copy NUL "%CWD%\%%~f" > NUL
)
:: 結果を表示
echo.
echo ^-^- 変換前 ^-^-
dir /b %CWD%
:: ファイル名を変更
for %%f in (%CWD%\*) do (
set f=%%~nxf
move "%CWD%\!f!" %CWD%\!f: =_!
)
:: 結果を表示
echo.
echo ^-^- 変換後 ^-^-
dir /b %CWD%
endlocal
goto :EOF
:A3
setlocal enabledelayedexpansion
set CWD=%~1
:: カレンダーを表示するバッチファイルが存在するか確認
if not exist "%HOME%\cal.bat" (
echo %SELF%: file not found: %HOME%\cal.bat >&2
exit /b 1
)
:: カレンダーを表示するバッチファイルを実行して日付を取得
set y=2014
for /l %%m in (1,1,12) do (
set t=
for /f "tokens=*" %%t in ('cal %%m %y% ^| more +2') do (
set t=!t! %%t
)
set m=%%m
if !m! lss 10 (
set m=0!m!
)
for %%d in (!t!) do (
set d=%%d
if !d! lss 10 (
set d=0!d!
)
(echo %y%/!m!/!d!) > %CWD%\%y%!m!!d!
)
)
:: 結果を表示
echo.
dir /w %CWD%
endlocal
goto :EOF
:A4
setlocal enabledelayedexpansion
set CWD=%~1
:: ファイルを作成
> %CWD%\a_ramen echo カレー
> %CWD%\a_cury echo ラーメン
> %CWD%\b_apple echo トマト
> %CWD%\b_tomato echo りんご
:: 結果を表示
echo.
echo ^-^- 変換前 ^-^-
findstr /r ".*" %CWD%\*
:: ファイル名を変更
for %%s in (a b) do (
set t=
for /f "tokens=*" %%f in ('dir /b %CWD%\%%s_*') do (
set t=%%f !t!
)
for /f "tokens=1,2" %%a in ("!t!") do (
move %CWD%\%%a %CWD%\%SELF%.tmp
move %CWD%\%%b %CWD%\%%a
move %CWD%\%SELF%.tmp %CWD%\%%b
)
)
:: 結果を表示
echo.
echo ^-^- 変換後 ^-^-
findstr /r ".*" %CWD%\*
endlocal
goto :EOF
:A5
setlocal enabledelayedexpansion
set CWD=%~1
:: ファイルを圧縮・展開するコマンドが存在するか確認
for %%f in (makecab.exe expand.exe) do (
if not exist "%%~$PATH:f" (
echo %SELF%: file not found: %%f >&2
exit /b 1
)
)
:: テスト 3を実行
call :A3 %CWD%
if %ERRORLEVEL% neq 0 (
echo %SELF%: script abended: A3 >&2
exit /b 1
)
:: 月単位のフォルダーを作成しながらファイルを移動
for %%f in (%CWD%\*) do (
set f=%%~nxf
set d=!f:~0,6!
if not exist "%CWD%\!d!\" (
md %CWD%\!d!
)
move %CWD%\!f! %CWD%\!d!
)
:: 結果を表示
echo.
tree /f %CWD%
:: ファイルを圧縮
for /f "tokens=*" %%d in ('dir /ad /b %CWD%') do (
set t=%%~nd
copy NUL %CWD%\!t!.tmp > NUL
for %%f in (%CWD%\%%d\*) do (
(echo %%f) >> %CWD%\!t!.tmp
)
makecab /f %CWD%\!t!.tmp ^
/d InfFileName=NUL ^
/d RptFileName=NUL ^
/d DiskDirectoryTemplate=%CWD% ^
/d CabinetNameTemplate=!t!.cab
if !ERRORLEVEL! neq 0 (
echo %SELF%: failed to compress: !t!.cab >&2
exit /b 1
)
del %CWD%\!t!.tmp
)
:: 結果を表示
for %%f in (%CWD%\*.cab) do (
set f=%%~nxf
echo.
echo ^-^- !f! ^-^-
expand -d %%f
if !ERRORLEVEL! neq 0 (
echo %SELF%: failed to expand: !f! >&2
exit /b 1
)
)
endlocal
goto :EOF
:A6
setlocal enabledelayedexpansion
set CWD=%~1
:: パス文字列を生成
for /l %%i in (1,1,100) do (
set t=!t!\a
)
:: フォルダーを作成
md %CWD%\%t%
:: 最下層のフォルダーへ移動
pushd %CWD%\%t%
:: ファイルを作成
copy NUL b > NUL
:: 結果を表示
echo.
cd
echo.
dir %CWD%\%t%
set i=0
set p=!CD:%CWD%=!
for %%i in (%p:\= %) do (
set /a i+=1
)
echo.
echo %SELF%: # of folders: %i%
:: 作業フォルダーへ移動
popd
endlocal
goto :EOF
:A7
setlocal enabledelayedexpansion
set CWD=%~1
:: テスト 6を実行
call :A6 %CWD%
if %ERRORLEVEL% neq 0 (
echo %SELF%: script abended: A6 >&2
exit /b 1
)
:: パス文字列を生成
for /l %%i in (1,1,100) do (
set t1=!t1!\a
)
for /l %%i in (1,1,50) do (
set t2=!t2!\a
)
:: ファイルが存在するか確認
if not exist "%CWD%\%t1%\b" (
echo %SELF%: file not found: %CWD%\%t1%\b >&2
exit /b 1
)
:: ファイルを移動
move %CWD%\%t1%\b %CWD%\%t2%
:: 50番目のフォルダーへ移動
pushd %CWD%\%t2%
:: 結果を表示
echo.
dir
set i=0
set p=!CD:%CWD%=!
for %%i in (%p:\= %) do (
set /a i+=1
)
echo.
echo %SELF%: # of folders: %i%
:: 作業フォルダーへ移動
popd
endlocal
goto :EOF
:A8
setlocal enabledelayedexpansion
set CWD=%~1
:: テスト 6を実行
call :A6 %CWD%
if %ERRORLEVEL% neq 0 (
echo %SELF%: script abended: A6 >&2
exit /b 1
)
:: パス文字列を生成
for /l %%i in (1,1,100) do (
set t=!t!\a
)
:: 最下層のフォルダーへ移動
cd %CWD%\%t%
:: 結果を表示
echo.
cd
:: 上の階層へ移動しながらフォルダーを削除
for /l %%i in (1,1,100) do (
if exist ".\b" (
del /q .\b
)
cd ..
rd .\a
)
:: 結果を表示
echo.
dir
endlocal
goto :EOF
位置パラメーターを指定せずに実行すると
C:\temp>2014-02-15.bat
Usage: 2014-02-15 NUMBER
とヘルプが表示されるので、 1 から 8 までの数字のなかから任意の値を指定して実行してください。