Yahoo! 知恵袋（q10155157145）

「Yahoo! 知恵袋」の以下の質問を解いてみました。

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10155157145

```bat:q10155157145.bat
@echo off

set SELF=%~n0
set HELP=usage: %SELF% STRING
set TEST=0

if %TEST% equ 1 (
  call :test
  exit /b 0
)

setlocal
  if "%~1" == "" (
    >&2 echo %HELP%
    exit /b 1
  )
  set str=%~1
  
  :: 1 day ago (%Y%m%d)
  call :get_n_days_ago 1 %DATE:/=% ymd
  
  :: current working directory
  set cwd=%~dp0
  set cwd=%cwd:~0,-1%
  
  echo.
  echo find "%str%" ^< "%cwd%\%ymd%.txt" ^> "%cwd%\%str%_%ymd%.txt"
  echo.
  choice /c YN /m "Are you sure you want to run this command?"
  if %ERRORLEVEL% equ 2 (
    >&2 echo %SELF%: process aborted
    exit /b 1
  )
  
  if not exist "%cwd%\%ymd%.txt" (
    >&2 echo %SELF%: file not found: %cwd%\%ymd%.txt
    exit /b 1
  )
  
  find "%str%" < "%cwd%\%ymd%.txt" > "%cwd%\%str%_%ymd%.txt" || (
    >&2 echo %SELF%: string pattern not matched: %str%
    exit /b 1
  )
  
  echo.
  echo %str%_%ymd%.txt ^>^>^>
  type "%cwd%\%str%_%ymd%.txt"
  echo ^<^<^< %str%_%ymd%.txt
endlocal
goto :EOF

:get_n_days_ago
setlocal enabledelayedexpansion
  set t= 030101001010
  
  set d1=%~2
  
  set y=%d1:~0,4%
  :: octal to decimal
  set /a m=1%d1:~4,2%-100
  set /a d=1%d1:~6,2%-100
  
  set n=%~1
  if %d% gtr %n% ( :: n means 1st to n-th
    set /a d-=%n%
  ) else (
    if %m% gtr 1 ( :: 1 means January
      set /a m-=1
    ) else (
      set /a y-=1
      set m=12
    )
    call set /a d=31-%%t:~!m!,1%%
    if !m! equ 2 ( :: 2 means February
      call :is_leap_year %y% || set /a d+=1
    )
    set /a d=!d!+%d%-%n%
  )
  
  if %m% lss 10 set m=0%m%
  if %d% lss 10 set d=0%d%
  
  set d2=%y%%m%%d%
endlocal & set %~3=%d2%
goto :EOF

:is_leap_year
setlocal
  set n=0
  
  set /a n=%1%%400
  if %n% equ 0 exit /b 1
  
  set /a n=%1%%100
  if %n% equ 0 exit /b 0
  
  set /a n=%1%%4
  if %n% equ 0 exit /b 1
  
  exit /b 0
endlocal
goto :EOF

:test
setlocal enabledelayedexpansion
  for %%d in (%DATE:/=% 20160101 20160401 20150301 20160301) do (
    call :get_n_days_ago 1 %%d d
    echo.
    echo %%d
    echo !d!
  )
endlocal
goto :EOF
```

２日分のログファイルを作成します。

```text:20160201.txt
2016-02-01: HOST-A: hit!
2016-02-01: HOST-B: miss!
2016-02-01: HOST-C: miss!
2016-02-01: HOST-D: miss!
2016-02-01: HOST-E: miss!

2016-02-01: HOST-A: hit!
2016-02-01: HOST-B: miss!
2016-02-01: HOST-C: miss!
2016-02-01: HOST-D: miss!
2016-02-01: HOST-E: miss!

2016-02-01: HOST-A: hit!
2016-02-01: HOST-B: miss!
2016-02-01: HOST-C: miss!
2016-02-01: HOST-D: miss!
2016-02-01: HOST-E: miss!
```

```text:20160202.txt
2016-02-02: HOST-A: hit!
2016-02-02: HOST-B: miss!
2016-02-02: HOST-C: miss!
2016-02-02: HOST-D: miss!
2016-02-02: HOST-E: miss!

2016-02-02: HOST-A: hit!
2016-02-02: HOST-B: miss!
2016-02-02: HOST-C: miss!
2016-02-02: HOST-D: miss!
2016-02-02: HOST-E: miss!

2016-02-02: HOST-A: hit!
2016-02-02: HOST-B: miss!
2016-02-02: HOST-C: miss!
2016-02-02: HOST-D: miss!
2016-02-02: HOST-E: miss!
```

ログファイルの更新日時を変更します。

```bat:
C:\sandbox>powershell
Windows PowerShell
Copyright (C) 2014 Microsoft Corporation. All rights reserved.

PS C:\sandbox> Set-ItemProperty 20160201.txt -Name LastWriteTime -Value "02/01/2016 09:00 AM"
PS C:\sandbox> Set-ItemProperty 20160202.txt -Name LastWriteTime -Value "02/02/2016 09:00 AM"
PS C:\sandbox> exit

C:\sandbox>dir 2016020*.txt
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は XXXX-XXXX です

 C:\sandbox のディレクトリ

2016/02/01  09:00               389 20160201.txt
2016/02/02  09:00               389 20160202.txt
```

バッチファイルを実行します。

```bat:
C:\sandbox>q10155157145.bat "HOST-A"

find "HOST-A" < "C:\sandbox\20160202.txt" > "C:\sandbox\HOST-A_20160202.txt"

Are you sure you want to run this command? [Y,N]? Y

HOST-A_20160202.txt >>>
2016-02-02: HOST-A: hit!
2016-02-02: HOST-A: hit!
2016-02-02: HOST-A: hit!
<<< HOST-A_20160202.txt
```

前日のファイル（20160202.txt）から検索文字列にマッチした行のみ抽出されることを確認しました。