上司「このフォルダーにあるファイルのリスト作って」

昨晩 Twitter のタイムラインを流れてきた

[上司「このフォルダーにあるファイルのリスト作って」（おーぷん２ちゃんねる）](http://hayabusa.open2ch.net/test/read.cgi/news4vip/1441461511/)

がおもしろかったので、ちょっと考えてみました。

# Q1．任意のフォルダーにあるファイルの一覧を作成

> 上司「このフォルダーにあるファイルのリスト作って」

`dir` コマンドだけでも充分なのですが、 `forfiles` コマンドなど探せばいろいろなやり方が見つかりそうです。

```
dir /s "任意のフォルダー"
```
```
where /r "任意のフォルダー" /t *.*
```
```
for /r "任意のフォルダー" %i in (*.*) do (echo %~fi  %~zi  %~ti)
```
```
forfiles /p "任意のフォルダー" /c "cmd /c echo @path  @fsize  @fdate  @ftime"
```

# Q2．サイトから ZIP 形式のファイルをダウンロード

> 上司「このサイトから ZIP ダウンロードしてくれ」

ファイルの一覧を取得する方法がわかりませんでした。なので、ダウンロードするファイルに一定の命名規則がない場合、一つずつファイル名を指定しなくてはならないのが難点ですね。

```
bitsadmin /transfer /download URL ファイル
```

ちなみに「BITS」とは「バックグラウンドインテリジェント転送サービス（Background Intelligent Transfer Service）」の略だそうです。

# Q3．特定の文字列を含むファイルを任意のフォルダーに移動

> 上司「Ｘに関することが記述されているファイルはＡに、Ｙが書かれているファイルはＢに格納してね」

`findstr` コマンドの実行結果から `:` を区切り文字としてファイル名を抽出してみました。

```
for /f "tokens=1 delims=:" %i in ('findstr /l "特定の文字列" *.*') do (move %i フォルダー)
```

これは `forfiles` コマンドでもできそうですね。

# Q4．特定の文字列を含むファイルを抽出

> 上司「ごめん、Ｘの取引の調査したいんだけど頼める？」
> 上司「この中のどこかにその取引について書かれているんだけどロストしちゃって。頼むわ」

文字列リテラルで検索する場合は

```
find "特定の文字列" *.*
```
```
findstr /l "特定の文字列" *.*
```

でよさそうです。 `findstr` コマンドの `/r` オプションを利用すれば、正規表現のような記法も可能です。

# Q5．（不明）

> 上司「ＸをＹにしてくれない？結構複雑だけどできる？」

後輩くんが高級言語で書きたがるくらい複雑な処理らしいのですが…具体的な条件や問題の意図がわからず断念しました。

# Q6．CSV 形式のファイルから特定の文字列を含む行を抽出

> 上司「この CSV からＸ店の取引のレコード取り出して」

Q4 と同じやり方でよさそうです。念のため `/n` オプションを指定して行数も出力するようにしています。

```
find /n "特定の文字列" *.csv
```
```
findstr /n /l "特定の文字列" *.csv
```

これも `findstr` コマンドの `/r` オプションを利用すれば、正規表現のような記法が可能です。

# Q7．任意のフォルダーの下にあるファイルのうち、ファイル名に特定の文字列を含むものを特定のフォルダーに全てコピー

> 上司「このサーバの中でファイル名にＸがついている奴をコピーしてここに格納しといて」

これは `forfiles` コマンドでできそうです。

```
forfiles /p "任意のフォルダー" /m "特定の文字列" /s /c "cmd /c copy @path 特定のフォルダー"
```

# Q8．既存のコマンドを任意の名前で実行

> 後輩「このディレクトリ内のファイルは…」（ｶﾀｶﾀ）
> 
> －－－－－－－ コマンドプロンプト －－－－－－－
> 'ls' は、内部コマンドまたは外部コマンド、
> 操作可能なプログラムまたはバッチ ファイルとして認識されていません。
> －－－－－－－ コマンドプロンプト －－－－－－－
> 
> 後輩「もおお！ Windows だた wwwwww」

むかしからある `doskey` コマンドで別名にマッピングすれば一丁あがりです。

```
doskey ls=dir
```

# Q9．プロンプトの出力形式を変更

> 後輩「～♪」（ｶﾀｶﾀ）
> 
> －－－－－－－ コマンドプロンプト －－－－－－－
> C:\Users\Desktop\エロ画像\洋物\Ｓクラス>ren 特エ
> ロ画像.jpg　報告書.jpg
> －－－－－－－ コマンドプロンプト －－－－－－－
> 
> 後輩「あああああああああああああ！」
> 後輩「ディレクトリ階層が深すぎてコマンドが改行されて見づらいよ…」

出力を見るかぎり、 `$P`（現在のドライブとパス）と `$G`（不等号）の間に `$_`（キャリッジリターンとラインフィード）を入れて表示を変えているようです。

```
prompt $P$_$G
```

# Q10．任意のフォルダーの下にあるファイルを特定のファイルで全て上書きコピー

> 上司「このテキストファイルにファイルを全部修正しておいて」
> 上司「絶対パスが書いてあるからそこからコピーしといてね」

これは Q7 と同じやり方でよさそうです。

```
forfiles /p "任意のフォルダー" /s /c "cmd /c copy 特定のファイル @path"
```

# Q11. 任意のフォルダーの下にあるファイルを任意の更新日時・作成日時に変更

> 上司「このフォルダにあるファイルの更新日時と作成日時を 2015/09/06 00:00:00 にしといて」

これはちょっとわかりませんでした。というのも、更新日時は現在時刻に変更できるのですが、作成日時までは変更できないからです。ちなみに `date` コマンドと `time` コマンドでシステムの日時を「2015/09/06 00:00:00」にセットして…となると、仮想環境上で実行したほうが無難かもしれません。

```
copy /b ファイル +
```

# その他

※103（103 番めのコメント）にまとめられているものです。

## 特定のプロセスを終了

> クリックすれば特定のプロセスを殺すバッチ作ったり…

`tasklist` や `taskkill` コマンドのこともときどき思い出してあげないと…（すっかり忘れてました）

```
taskkill /f /im "特定のプロセスのイメージ名" /t
```

## 一定時間経過後にコマンドを実行

> 一定時間後にプロセス実行したり…

むかしは `ping` コマンドで

```
ping -n 3 127.0.0.1 > NUL 2>&1
```

のようにしていたのですが、 `timeout` コマンドのおかげで便利になりました。

```
timeout /t 秒数 & コマンド
```

ちなみに間に `&` を一つ入れているのは、 `timeout` コマンドの終了ステータスによらず次のコマンドを実行したかったからです。

## Windows をシャットダウン

> Windows 8 のシャットダウンにバッチ使ったり…

```
shutdown /s
```

```
shutdown /p
```

`shutdown` コマンドにもいろいろなオプションがあってびっくりしました。

# まとめ

いろいろ調べているうちに %SYSTEMROOT%\system32 の下に新たなコマンドが増えていることに気がつきました。

```
dir %SYSTEMROOT%\system32\*.exe
```

を実行すると外部コマンドと思われるものがたくさん出てきますが、なかにはファイル名からではどう使うのか見当のつかないものもちらほら…

いずれ時間のある時に各コマンドに `/?` オプションを指定したり `help` コマンドを実行したりして、使い方を覗いてみようかと思います。