やりたいことができたのでここに書き留めておきます。
本当にいろいろなサイトを参考にさせていただきました。色々見過ぎてどこのサイトからどんな内容を参考させていただいたかわからないくらいです。
本当にありがとうございます。各サイトの皆様ありがとうございます。
このプログラムは、CSVファイルを配列のようにして利用したいとの思いで書いてみたものです。
専門家の方から見たらいっぱい不手際があるかもしれませんが、もし誰かの参考になればうれしいです。
各々の責任でテストしてみてください。あくまでもど素人が書いたものですので。ご了承願います。
Windowsのバッチファイルとして動くと思います。
CSVは、横方向(列)にカンマ区切りでフィールド(項目)があり、縦方向(行)にレコードのような構成だと思います。
これを
field[縦方向(行)番号][横方向(列)番号]
という変数に入れていくプログラムです。
このプログラムは、***.batのようなバッチファイルの中に記述します。 csvファイルを 引数として渡します
例:sample.bat sampledata.csv
@echo off
setlocal enabledelayedexpansion
cd %~dp0
set /a "n=0"
REM findstr /n であえて先頭に行番号をつけ1行ごと取り出しdelimisで先頭の行番号(数値)を除去する
REM その後の処理で行番号直後の : を削除する。これによりなるべくいろいろな文字を利用できるように施してある
for /f "tokens=* delims=0123456789 eol=" %%a in ('findstr /n "^" %1') do (
set /a "m=0"
set /a "n+=1"
set "RR=%%a"
REM findstrでつけた行番号の後にある:を削除している
set "RR=!RR:~1!"
REM もし改行だけならデータがないので分割処理を飛ばす
if not [!RR!]==[] (
REM ここで一旦わざと半角スペースをつけてデータがないフィールドにいったんスペースで満たしSUB-TRIMで削除
set "RR=!RR:,= ,!"
REM データ確認用に出力。実際の利用では削除してもよい
echo !RR!
call :split
)
)
endlocal
exit /b 0
:split
for /F "usebackq tokens=1* delims=," %%A in ('!RR!') do (
set /a "m+=1"
REM %%~Aでcsv内の引用句””を削除
set "TRIM=%%~A"
REM SUB-TRIMのサブルーチンで文字列前後の空白を削除
call :SUB_TRIM !TRIM!
set "field[!n!][!m!]=!TRIM!"
set "RR=%%B"
REM データ確認用に出力。実際の利用では削除してもよい
call :SUB-ECHO
if %%B=="" ( goto :END_LOOP )
goto :split
)
:END_LOOP
exit /b 0
REM 文字列の前後の空白のみ削除
:SUB_TRIM
SET TRIM=%*
exit /b 0
REM 配列内のデータ確認
:SUB-ECHO
echo field[%n%][%m%]=!field[%n%][%m%]!
exit /b 0
set 文は、”で区切ったほうが良いと書いてありましたので”で括っています。
2022.08.16 繰り返しの記述で call :split として、if %%B=="" ( goto :END_LOOP ) の前に記述していましたが goto :split として、if %%B=="" ( goto :END_LOOP ) の後に記述しなおしました。
2023.01.29 データ確認用のecho出力がうまくいっていなかったのでサブルーチン化しました。
for /f "tokens=* delims=0123456789 eol=" %%a in ('findstr /n "^" %1') do (
この行は、こちらのサイトのものを参考にしました。ありがとうございます。
%1引数のところをスぺース付きのファイル名などで別の変数で作って
set FILE=c:\test\test file.csv
for /f "tokens=* delims=0123456789 eol=" %%a in ('findstr /n "^" "!FILE!"') do (
とするとうまく動きませんでした。
そこで"^"の部分を"^^"としたらうまく動きました。
for /f "tokens=* delims=0123456789 eol=" %%a in ('findstr /n "^^" "!FILE!"') do (
:split
ここ以降に書かれたサブルーチンで、順番に読み込まれた行のデータから、最初の左端にあるフィールド(項目)を1つずつ読み込んで配列化していきます。
tokens=1*で左端1フィールドと残りに分けます。%%Aを指定していますので、%%Aには 左端1フィールド、残り(2フィールド以降)は、%%Bに入ります。
%%Bの残りをまた、RRの変数へ入れて繰り返すことで全てのフィールドを配列に入れます。