LoginSignup
4
3

More than 5 years have passed since last update.

第9回 シェル芸勉強会

Last updated at Posted at 2014-04-07

シェル芸(マウスをつかわず、ソースコードものこさず、 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 までの数字のなかから任意の値を指定して実行してください。

4
3
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
4
3