【第9回】フォルダ内のファイル名一覧取得方法 と 文字列操作方法について(WindowsとMacOS対象)

#はじめに
一般的にフォルダ内にあるファイルを一覧出力する際には、プロンプト上でOSコマンドの”dir”や"ls"を実行する方法が用いられます。

HeartCore　Roboからも上記のOSコマンドを実行して、出力結果を変数に格納することが可能です。ロボットがWindows Explorerを開いて1つ1つファイルを選択するより確実な方法です。

今回HeartCore Roboでファイル名を取得する方法のイメージです：
Windows > コマンドプロンプト > dirコマンドで対象ディレクトリ指定 > 出力結果からファイル名を件数分取得する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/80208c5e-204a-0e11-dd9b-04e189bfd58c.png)

(Windows Explorerで表示したファイル一覧)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/459d9fec-af04-5b00-305f-6f0934adcf8d.png)

併せてMacOSでファイル名を取得する方法も記載します。

また今回は、HeartCore Robo文字列操作コマンドを使用して、OSコマンドの出力結果からファイル名のみを取り出す方法もカバーします。文字列操作は様々なロボットで応用が効くので是非マスターして下さい。


#Execコマンドを使用してみる

HeartCore Roboには"Exec"コマンドが用意されており、ローカルマシンのOSコマンドを実行することが可能です。コマンドの説明・引数・結果が格納される変数の一覧は下記のオンラインリファレンスを参照下さい。

https://www.heartcorerobo.com/hcrobodesktop/docs/scripting/commref.html#exec

Execコマンドで実行した結果はシステム変数
>{_EXEC_OUTPUT}

に格納されます。

以下実際の取得方法についてWindows用サンプルを記載します。

```javascript
//ディレクトリ指定
Var Path="C:\Temp\Files”

//Exec コマンドでコマンドプロンプトを起動、引数には上記のディレクトリ変数を指定
//コマンドプロンプト(cmd.exe) “/c”オプションでコマンド実行後終了させる
//dirコマンド ”/b”オプションで指定したフォルダ内ファイル名のみを出力

Exec “cmd.exe /c dir /b {Path}”

//確認用に結果をログ出力
Log {_EXEC_OUTPUT}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/047d9355-d6db-4ad6-159a-79509564ec18.png)

結果：
>Dec 7, 2018 2:27:36 PM INFO: 新しいテキスト ドキュメント - コピー (2).txt
新しいテキスト ドキュメント - コピー (3).txt
新しいテキスト ドキュメント - コピー.txt 新しいテキスト ドキュメント.txt

MacOS上のファイルを取得するにはターミナルと同様lsコマンドを使用します。

```javascript
//ディレクトリ指定
Var Path="/Users/demouser/Temp"

//Exec コマンドでコマンドプロンプトを起動、引数には上記のディレクトリ変数を指定
//lsコマンド ”-1”オプションで指定したフォルダ内ファイル名のみを出力

Exec "ls -1 {Path}"

//確認用に結果をログ出力
Log {_EXEC_OUTPUT}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/36b81c29-a44d-7d53-6dec-db5927ee798f.png)
↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/1fc1dfde-49d2-1640-96a1-5991576fe91a.png)


#出力結果を文字列操作を使用してファイル名に分割してみる

上記で確認した通り、結果は{_EXEC_OUTPUT}変数に格納されますが、改行コードを含めて「１つの文字列」として格納されているため、String spllitコマンドを使用して改行コード(¥n)でファイル数に分割する必要があります。

分割された分だけ変数に格納されるので、全ての変数から値を取得するにはfor文を使用します。カウンタには分割された数が格納されるシステム変数{_STRING_COUNT}を使用します。

文字列操作を行うStringコマンドの詳細については下記のオンラインリファレンスを参照下さい。
https://www.heartcorerobo.com/hcrobodesktop/docs/scripting/commref.html#string

（補足）
Stringコマンドの命令については java.lang.String のJavaクラスメソッド名から派生しています。
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html

以下実際の文字列操作方法についてサンプルを記載します。

```javascript
//出力結果変数{_EXEC_OUTPUT}を改行コード(¥n)で分割
//同時に”FileName”という分割された値を格納する変数を宣言
String "split" "{_EXEC_OUTPUT}" var="FileName" pattern="\n”

//分割分のファイル名を取得して{FileName_{for文のカウンタ}}変数に格納

for (i=1; {i}<{_STRING_COUNT}+1; i={i}+1) {

    //確認用に結果をログ出力
    Log {FileName{i}}
}
```

結果：
>Dec 7, 2018 2:27:36 PM INFO: 新しいテキスト ドキュメント - コピー (2).txt (   ファイル:ディレクトリ内ファイル一覧取得.tpr、行:19: Log {FileName{i}}) 
Dec 7, 2018 2:27:36 PM INFO: 新しいテキスト ドキュメント - コピー (3).txt (   ファイル:ディレクトリ内ファイル一覧取得.tpr、行:19:
 Log {FileName{i}}) 
Dec 7, 2018 2:27:36 PM INFO: 新しいテキスト ドキュメント - コピー.txt (   ファイル:ディレクトリ内ファイル一覧取得.tpr、行:19: Log {FileName{i}}) 
Dec 7, 2018 2:27:36 PM INFO: 新しいテキスト ドキュメント.txt (   ファイル:ディレクトリ内ファイル一覧取得.tpr、行:19: Log {FileName{i}})

# 上記を応用して指定したフォルダ内のファイル全てをHeartCore Roboに1つ1つ開かせてみる

下記に応用編サンプルを記載します(Windows用)。

```javascript
//ディレクトリ指定
Var Path="C:\Temp\Files"

//Exec コマンドでコマンドプロンプトを起動、引数には上記のディレクトリ変数を指定
//コマンドプロンプト(cmd.exe) “/c”オプションでコマンド実行後終了させる
//dirコマンド ”/b”オプションで指定したフォルダ内ファイル名のみを出力
Exec "cmd.exe /c dir /b {Path}"

//確認用に結果をログ出力
Log {_EXEC_OUTPUT}

//出力結果変数{_EXEC_OUTPUT}を改行コード(¥n)で分割
//同時に”FileName”という分割された値を格納する変数を宣言
String "split" "{_EXEC_OUTPUT}" var="FileName" pattern="\n"

//分割分のファイル名を取得して{FileName_{for文のカウンタ}}変数に格納
for (i=1; {i}<{_STRING_COUNT}+1; i={i}+1) {

    //「ファイル名を指定して実行」を起動
    Press "Windows+R"
    //指定したディレクト+取得したファイル名を入力
    Paste "{Path}\{FileName{i}}"
    //ENTERキーで実行（実行後に1秒待機）
    Press "ENTER" wait="1s"
    
}

Report "results.xml"
```

結果：

HeartCore Roboが下記Windows機能「ファイルを指定して実行」を利用してフォルダ内のファイル数分のテキストファイルをメモ帳で開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/df8ceec4-3221-adaa-550b-9d7ff882998d.png)
↓ (x4回)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/c6c23284-a977-436f-3ced-41867d81b02c.png)

#【発展編】特定の文字列が含まれているファイル名のみを指定してファイルを開いてみる
If文の条件に"contains"キーワードを使用します。使用例として、"contain”以下に拡張子を指定すれば特定のファイルの種類のみを開く事が可能です。

"containts"などの条件演算子については下記のブール式に関するリファレンスご参照下さい。
https://www.heartcorerobo.com/hcrobodesktop/docs/scripting/commref.html#boolean

下記のサンプルはファイル名に特定の文字"(2)"があるファイルのみを開きます。

```javascript
//ディレクトリ指定
Var Path="C:\Temp\Files"

//Exec コマンドでコマンドプロンプトを起動、引数には上記のディレクトリ変数を指定
//コマンドプロンプト(cmd.exe) “/c”オプションでコマンド実行後終了させる
//dirコマンド ”/b”オプションで指定したフォルダ内ファイル名のみを出力
Exec "cmd.exe /c dir /b {Path}"

//確認用に結果をログ出力
Log {_EXEC_OUTPUT}

//出力結果変数{_EXEC_OUTPUT}を改行コードで分割して変数に格納
String "split" "{_EXEC_OUTPUT}" var="FileName" pattern="\n"

//分割分のファイル名を取得して{FileName_{for文のカウンタ}}変数に格納
for (i=1; {i}<{_STRING_COUNT}+1; i={i}+1) {
    
    //ターゲットとなるファイル名に指定したキーワードが含まれている場合のみファイルを開く
    if ({FileName{i}} contains "(2)") {
        //「ファイル名を指定して実行」を起動
        Press "Windows+R"
        //指定したディレクト+取得したファイル名を入力
        Paste "{Path}\{FileName{i}}"
        //ENTERキーで実行（実行後に1秒待機）
        Press "ENTER" wait="1s"
    }
}

Report "results.xml"
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/46151115-e05e-d8c8-16b1-3fa4f58d3348.png)

結果：
上記"contains"キーワードで指定した"(2)"があるファイルのみが開かれる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254242/2f9a0c13-0187-0cbe-ee2f-5fecea459abb.png)

#次回について
次回は、実運用に必要なロボットの展開（デプロイメント）方法についてカバーします。HeartCore Roboのメリットの一つである「OS自体のスケジュール機能を利用した無人運用」を利用して、夜中や朝方の特定の時間にロボットを自動起動させる方法を記載する予定です。