- 締切済み
DOSプロンプトのテキストファイルから取得したフィールドがデータ無しの場合の認識方法
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プロンプトコマンドによるバッチ処理のみで行う必要があります。 宜しくお願いします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- iriyak
- ベストアンサー率48% (40/82)
こんにちは。 > 又環境は、銀行のサーバで実装するのでフリーソフトはもちろんparlやWSH等のインストールも許されていない為、DOSプロンプトコマンドによるバッチ処理のみで行う必要があります。 ANo.1, ANo.2 と類似の問いかけとなりますが、こうした制約がどこからくるものなのか、ユーザに問い合わせて正確な把握にトライされてはいかがでしょうか。 (回答者のコメント) 回答者も何度かサーバに持ち込む場合の制約を課せられた経験があります。ただ、大概は素性の知れないプログラムがシステムにもぐりこんだ際の様々なリスクにどう処するか、という観点がほとんどです。素性が知れている、とはどういう意味か、回答者は、それが使用するライブラリがわかっていて、アルゴリズムも(ソースコードから)わかっていて、それがどんな挙動を示すか見通せている、という意味で用いています。 ユーザにそのことを理解してもらい、リスクを分析/評価し、未来起こることに腹をくくる決断をユーザがするのであれば、ユーザは DOS プロンプト (cmd.exe) だけで実装せよ、という制約をもう少し緩められるのでは?? と回答者は推測します。もちろん、リスクの分析/評価に際して会社の方針をすべてに優先すべき場合もあります。それゆえ、ユーザにその考え方はどこから来ているのかを確認してみては? とコメントしました。
- tatsu99
- ベストアンサー率52% (391/751)
#4です。失礼しました。質問を取り消します。
- tatsu99
- ベストアンサー率52% (391/751)
処理をするプログラムの実体は、perlとかC言語とかで実装し、それをDOSのコマンドプロンプトのバッチから呼び出すのが、ふつうだと思うのですが、それではダメなのでしょうか?
補足
だめです。あくまでもバッチでとの要望なので。 理由はここで議論すべきことではないのでやめます。
- Eighty8
- ベストアンサー率84% (21/25)
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, 【実行結果ファイル: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 教えていただいた、「カンマ,が複数連続している場合にスペースを挟む」 の処理がポイントでした。 そこに最初と最後にもカンマ,を付けたら出来ました。 有難う御座いました。
補足
ありがとうございます。 ただご教示頂いた例ですと行の最初のフィールドと最後のフィールドが変換されない様です。 例えば入力ファイルが、 <<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に変換出来る様にしたいです。 もうすこしです。 有り難うございます。
- lv4u
- ベストアンサー率27% (1862/6715)
>>環境は、銀行のサーバで実装するのでフリーソフトはもちろんparlやWSH等のインストールも許されていない為、DOSプロンプトコマンドによるバッチ処理のみで行う必要があります。 「無理です!」って答えたほうがいいと思います。できるというなら、「やり方を教えてください」と言いましょう。
補足
客に出来ないかと頼まれているのでとりあえずがんばって調べている最中です。
- pick52
- ベストアンサー率35% (166/466)
> 又環境は、銀行のサーバで実装するのでフリーソフトはもちろん > parlやWSH等のインストールも許されていない為、DOSプロンプト > コマンドによるバッチ処理のみで行う必要があります。 ここが気になるのですが通常、サーバならPerlは標準インストール されているはずですし、OSがWindowsならWSHはOSの一部ですので よほど特殊な環境でない限り使用できるはずです。 あと、ローカルで処理してサーバにアップするという方法もあります けどサーバで処理したいということなのでしょうか。
補足
日々出力されるファイルに対し、サーバ上のバッチ処理で自動化する必要があると言うことです。
補足
色々とご意見有り難うございます。 ただあくまでもバッチでと言う要望なのでANo.1でもコメントしたとおり、まだギブアップせずまずは可能なのかを調査している段階です。 またここではその様な議論をすると言うよりバッチで可能かどうかの事実関係が知りたいです。