CSVファイルから各フィールドを取得し、なにも入っていない場合は固定値を入れると言う処理を、DOSのコマンドプロンプトによるバッチで行ってほしいと言うユーザ要望に答えなくてはなりません。
【入力ファイル】
<<AAA.csv>>
aaa,,bbb,,ccc,ddd
iii,jjj,kkk,lll,mmm,nnn
eee,,fff,,ggg,hhh
このAAA.csvを入力情報にして、
カンマ区切りの何も入っていないフィールドを認識し、
上記ファイルで言うと、
各行の2項目に何も入っていない場合は222を、
各行の4項目に何も入っていない場合333を入れる、
と言う処理を作る必要があります。
上記に説明した処理での出力結果は以下の様になります。
【出力ファイル】
<<BBB.csv>>
aaa,222,bbb,333,ccc,ddd
iii,jjj,kkk,lll,mmm,nnn
eee,222,fff,333,ggg,hhh
forやsetを駆使してフィールドの取得や変換は出来たのですが、
取得したフィールドに何も入っていなかった場合に固定値を入れる処理で行き詰っています。
何か良い方法があれば教えてください。
ちなみに入力や出力ファイルはタブ区切りのTSVファイル形式の場合もあります。
又環境は、銀行のサーバで実装するのでフリーソフトはもちろんparlやWSH等のインストールも許されていない為、DOSプロンプトコマンドによるバッチ処理のみで行う必要があります。
宜しくお願いします。
A 回答 (6件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
> 又環境は、銀行のサーバで実装するのでフリーソフトはもちろん
> parlやWSH等のインストールも許されていない為、DOSプロンプト
> コマンドによるバッチ処理のみで行う必要があります。
ここが気になるのですが通常、サーバならPerlは標準インストール
されているはずですし、OSがWindowsならWSHはOSの一部ですので
よほど特殊な環境でない限り使用できるはずです。
あと、ローカルで処理してサーバにアップするという方法もあります
けどサーバで処理したいということなのでしょうか。
No.3
- 回答日時:
for文で分解すると連続したデリミタが一つの区切りに扱われてしまって空フィールドが判断できない、という感じでしょうか?
(ハズしていたら以下は無視してください)
かなり強引な気がしますが以下のようなバッチではダメでしょうか?
(遅延環境変数展開を使っているのでcmd /V:ONで起動する必要があります)
@echo off
for /F "delims=" %%L in ( %1 ) do call :Sub "%%L"
goto :EOF
rem 行単位の処理
:Sub
setlocal
rem 先頭と末尾の引用符除去
set LINE=%1
set LINE=%LINE:~1,-1%
rem カンマ,が複数連続している場合にスペースを挟む
:Loop
set LINE=%LINE:,,=, ,%
echo %LINE% | find ",," > null
if %ERRORLEVEL% EQU 0 goto :Loop
rem カンマ,区切りに分解してスペース1コならばフィールド番号に置き換えて連結
for /F "tokens=1-6 delims=," %%M in ( "%LINE%" ) do (
set RESULT=
if "%%M"==" " (set RESULT=111) else (set RESULT=%%M)
if "%%N"==" " (set RESULT=!RESULT!,222) else (set RESULT=!RESULT!,%%N)
if "%%O"==" " (set RESULT=!RESULT!,333) else (set RESULT=!RESULT!,%%O)
if "%%P"==" " (set RESULT=!RESULT!,444) else (set RESULT=!RESULT!,%%P)
if "%%Q"==" " (set RESULT=!RESULT!,555) else (set RESULT=!RESULT!,%%Q)
if "%%R"==" " (set RESULT=!RESULT!,666) else (set RESULT=!RESULT!,%%R)
echo !RESULT!
)
endlocal
goto :EOF
上記のままだと
・フィールド数が固定
・スペースが複数入っている場合は空フィールドとして扱われない
・%文字が入っていた場合が考慮されていない
・デリミタはカンマのみ
といった問題がありますが参考になれば。
#でもこれだけのことをするならきちんと言語を使って加工するべきな気がします
この回答への補足
ありがとうございます。
ただご教示頂いた例ですと行の最初のフィールドと最後のフィールドが変換されない様です。
例えば入力ファイルが、
<<CCC.csv>>
,,bbb,,ccc,ddd
iii,jjj,kkk,lll,mmm,nnn
eee,,fff,,ggg,
の様に、
1行目の最初と3行目の最後のフィールドになにも入っていなかった場合、
出力ファイルをご教示頂いたバッチの変換で、
<<DDD.csv>>
111,222,bbb,333,ccc,ddd
iii,jjj,kkk,lll,mmm,nnn
eee,222,fff,333,ggg,666
と行った様に、
一行目の最初のフィールドは111に、
三行目の最初のフィールドは666に変換出来る様にしたいです。
もうすこしです。
有り難うございます。
おかげさまで補足に書いた内容も解消できました。
頂いた例を元に下記の様に作成しました。
なお自動ジョブによりこのバッチが起動する様になるため、
遅延環境変数展開を使用しない方法に変えました。
【入力ファイル】
<<CCC.csv>>
,,bbb,,ccc,ddd
iii,jjj,kkk,lll,mmm,nnn
eee,,fff,,ggg,
【実行結果ファイル:EEE.csv】
111,222,bbb,444,ccc,ddd
iii,jjj,kkk,lll,mmm,nnn
eee,222,fff,444,ggg,666
【実行したバッチファイル】
echo off
for /F "delims=" %%L in ( CCC.csv ) do call :Sub "%%L" >>DDD.csv
for /F "tokens=1-6 delims=," %%a in (DDD.csv) do (
set A=%%a
set B=%%b
set C=%%c
set D=%%d
set E=%%e
set F=%%f
call :sub0
) >> EEE.csv
goto :EOF
rem 行単位の処理
:Sub
setlocal
rem 先頭と末尾の引用符を除去し、カンマ,に置換え
set LINE=%1
set LINE=,%LINE:~1,-1%,
rem カンマ,が複数連続している場合にスペースを挟む
:Loop
set LINE=%LINE:,,=, ,%
echo %LINE% | find ",," > null
if %ERRORLEVEL% EQU 0 goto :Loop
echo %LINE%
del null
goto :EOF
:sub0
if "%A%"==" " set A=111
if "%B%"==" " set B=222
if "%C%"==" " set C=333
if "%D%"==" " set D=444
if "%E%"==" " set E=555
if "%F%"==" " set F=666
echo %A%,%B%,%C%,%D%,%E%,%F%
goto :EOF
教えていただいた、「カンマ,が複数連続している場合にスペースを挟む」
の処理がポイントでした。
そこに最初と最後にもカンマ,を付けたら出来ました。
有難う御座いました。
No.6
- 回答日時:
こんにちは。
> 又環境は、銀行のサーバで実装するのでフリーソフトはもちろんparlやWSH等のインストールも許されていない為、DOSプロンプトコマンドによるバッチ処理のみで行う必要があります。
ANo.1, ANo.2 と類似の問いかけとなりますが、こうした制約がどこからくるものなのか、ユーザに問い合わせて正確な把握にトライされてはいかがでしょうか。
(回答者のコメント)
回答者も何度かサーバに持ち込む場合の制約を課せられた経験があります。ただ、大概は素性の知れないプログラムがシステムにもぐりこんだ際の様々なリスクにどう処するか、という観点がほとんどです。素性が知れている、とはどういう意味か、回答者は、それが使用するライブラリがわかっていて、アルゴリズムも(ソースコードから)わかっていて、それがどんな挙動を示すか見通せている、という意味で用いています。
ユーザにそのことを理解してもらい、リスクを分析/評価し、未来起こることに腹をくくる決断をユーザがするのであれば、ユーザは DOS プロンプト (cmd.exe) だけで実装せよ、という制約をもう少し緩められるのでは?? と回答者は推測します。もちろん、リスクの分析/評価に際して会社の方針をすべてに優先すべき場合もあります。それゆえ、ユーザにその考え方はどこから来ているのかを確認してみては? とコメントしました。
この回答への補足
色々とご意見有り難うございます。
ただあくまでもバッチでと言う要望なのでANo.1でもコメントしたとおり、まだギブアップせずまずは可能なのかを調査している段階です。
またここではその様な議論をすると言うよりバッチで可能かどうかの事実関係が知りたいです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- SQL Server ACCESSで表が作りたく、そのためのSQL文や設定方法を教えてください。 1 2022/08/15 12:28
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- システム CSVファイルのマッピング処理の省力化 1 2022/11/24 00:01
- Perl perl このテキストファイルを簡単に配列に入れるには? 2 2022/04/27 20:24
- Excel(エクセル) CSVファイルがカンマ区切りにならない。対処法を教えていただきたいです。 仕事でSMS一斉送信ができ 2 2022/07/01 21:24
- SQL Server ACCESSで3ファイルを結合して、表を作成するやり方を教えて下さい。 17 2022/08/15 20:34
- Visual Basic(VBA) 【VBA】特定の文字で改行(次の行)に行きたい。 3 2022/04/11 17:20
- HTML・CSS HTMLタグのあるCSVファイルを利用する方法 4 2023/03/19 14:41
- Access(アクセス) access,vbaでフォルダ内のファイルをテーブルにインポート、ファイル名もフィールドに追加したい 1 2022/08/31 11:11
- Visual Basic(VBA) VBAで特定の場所にあるCSVファイル(複数)から特定場所を抜き出してExcelに転記したいです。 11 2023/05/23 16:29
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
便利なbatファイル
-
0バイトファイルの判断
-
勝手にショートカットのリンク...
-
jw cadの名前をつけて保存・・...
-
メモ帳を保存せずに誤って閉じ...
-
Googleドライブにインターネッ...
-
VBAでFormat がうまく使えない
-
シェルスクリプトでFTPの実行結...
-
DVD-Rなのに再書き込みや削除が...
-
Debug Assertion Failed?
-
Excel2016 シート移動(ハイパ...
-
ショートカットファイルが開け...
-
C:\\Users\\All Users がエク...
-
craving explorerが開けません!!
-
フォルダを間違って削除しない...
-
急いでいます。XDWファイルの開...
-
Wordのデータが毎回破損してしまう
-
レジストリ変更が反映されません!
-
LTspiceのTime Stepエラーについて
-
不明なソフトウェア例外(0xe06...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
0バイトファイルの判断
-
特定の列の抽出
-
便利なbatファイル
-
バッチでファイルの読み込み
-
メモ帳を保存せずに誤って閉じ...
-
jw cadの名前をつけて保存・・...
-
DVD-Rなのに再書き込みや削除が...
-
Googleドライブにインターネッ...
-
急いでいます。XDWファイルの開...
-
ショートカットファイルが開け...
-
Debug Assertion Failed?
-
勝手にショートカットのリンク...
-
Thunderbirdのプロファイルが読...
-
windows defenderで質問です。 ...
-
VBAでFormat がうまく使えない
-
フォルダを間違って削除しない...
-
C:\\Users\\All Users がエク...
-
シェルスクリプトでFTPの実行結...
-
NET USE コマンドでエ...
-
Photoshopのデータの保存場所に...
おすすめ情報