質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • bash

    698questions

    bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

while文にiconvの結果を流し込むと処理が必ず飛び飛びになる

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 777

yumetodo

score 2566

#!/bin/bash
# @param input_file input file name
# @param prefix C-Preprocesser-Macro-Function name
# @param need_double_quote_index...
function convert_csv(){
  # argument
  readonly input_file=$1
  readonly prefix=$2
  shift 2
  local need_double_quote_index=($@)

  readonly need_double_quote_index_len=${#need_double_quote_index[@]}
  #write BOM
  echo -en '\xef\xbb\xbf'
  local line_string
  local is_first_line=1
  while read -r line_string; do
    if (( 1==is_first_line )); then
      is_first_line=0
      echo "//PREFIX,${line_string:0:-1},POSTFIX"
    else
        IFS_BACKUP=$IFS
        IFS=','
        elements=($line_string)
        IFS=$IFS_BACKUP
        local re="${prefix}(,"
        local i=0
        local j=0
        local e
        local tmp
        # debug print
        echo "${line_string}" >&2
        for e in "${elements[@]}"; do
          if (( i < need_double_quote_index_len && j == need_double_quote_index[i] )); then
            # ダブルクオートで囲う必要がある時
            re="${re}\"${e}\","
            (( i++ ))
          else
            read -p "Press [Enter] key to start backup..."
            tmp=$(echo "${e}" | sed -e 's/\//./')
            re="${re}${tmp},"
          fi
          (( j++ ))
        done
        echo "${re:0:-1},)"
    fi
  done < <(iconv -f cp932 -t UTF-8 "${input_file}")
}
echo "converting csv..."
# convert_csv './ships.csv' 'SHIP' 1 > 'KCS_CUI/source/ships_test.csv'
convert_csv './slotitems.csv' 'WEAPON' 1 2 > 'KCS_CUI/source/slotitems_test.csv'
echo "done."

こういうコードを書いたのですが
https://github.com/YSRKEN/KanColleSimulator_KAI/blob/2fae104567b8c26029fbf46c49a178f05dd445c1/csv_convert.sh

実行結果が必ず

$./csv_convert.sh
converting csv...
1,12cm単装砲,主砲,0,1,0,0,1,0,0,0,0,1
13,61cm三連装魚雷,魚雷,0,0,5,0,0,0,0,0,0,1
25,零式水上偵察機,水上偵察機,0,0,0,1,1,2,1,0,5,0
37,7.7mm機銃,対空機銃,0,0,0,0,2,0,0,1,0,0
49,25mm単装機銃,対空機銃,0,0,0,0,4,0,0,1,0,0
61,二式艦上偵察機,艦上偵察機,0,0,0,0,1,0,3,0,7,0
73,増設バルジ(大型艦),追加装甲(大型),9,0,0,0,0,0,0,-3,0,0
85,3.7cm FlaK M42,対空機銃,0,1,0,0,8,0,1,0,0,0
97,九九式艦爆(熟練),艦上爆撃機,0,0,0,7,1,4,2,0,2,0
109,零戦52型丙(六〇一空),艦上戦闘機,0,0,0,0,9,0,1,1,0,0
121,94式高射装置,高射装置,0,0,0,0,3,0,0,1,0,0
133,381mm/50 三連装砲,主砲,0,20,0,0,2,0,-3,-1,0,4
145,戦闘糧食,戦闘糧食,0,0,0,0,0,0,0,0,0,0
157,零式艦戦53型(岩本隊),艦上戦闘機,0,0,0,0,12,0,2,4,3,0
169,一式陸攻,陸上攻撃機,0,0,10,12,2,2,0,0,3,0
181,零式艦戦32型,艦上戦闘機,0,0,0,0,5,0,0,2,0,0
501,5inch単装砲,主砲,0,1,0,0,0,0,0,0,0,1
513,21inch魚雷前期型,魚雷,0,0,2,0,0,0,0,0,0,1
525,深海棲艦偵察機,水上偵察機,0,0,0,1,1,1,0,0,5,0
537,12.7mm機銃,対空機銃,0,0,0,0,2,0,0,0,0,0
549,深海復讐艦攻,艦上攻撃機,0,0,13,0,4,5,2,0,5,0
561,深海解放陸爆,艦上爆撃機,0,0,0,11,3,5,1,0,3,0
done.

のようにとびとびになります。csv自体は

装備ID,装備名,種別,装甲,火力,雷撃,爆装,対空,対潜,命中,回避,索敵,射程
1,12cm単装砲,主砲,0,1,0,0,1,0,0,0,0,1
2,12.7cm連装砲,主砲,0,2,0,0,2,0,0,0,0,1
3,10cm連装高角砲,主砲,0,2,0,0,7,0,0,0,0,1
.
.
.
190,38.1cm Mk.I連装砲,主砲,0,18,0,0,1,0,1,0,0,3
191,QF 2ポンド8連装ポンポン砲,対空機銃,0,1,0,0,10,0,0,0,0,0
192,38.1cm Mk.I/N連装砲改,主砲,0,19,0,0,3,0,2,0,0,3
501,5inch単装砲,主砲,0,1,0,0,0,0,0,0,0,1
502,5inch連装砲,主砲,0,2,0,0,0,0,0,0,0,1
503,3inch単装高角砲,主砲,0,1,0,0,1,0,0,0,0,1
.
.
.
568,16inch三連装砲,主砲,0,24,0,0,3,0,4,0,0,3
569,深海偵察飛行艇,水上偵察機,0,3,0,0,1,2,8,0,9,0
570,高速深海魚雷 mod.2,魚雷,0,0,13,0,0,0,3,0,0,1

のようになっています。
https://github.com/YSRKEN/KanColleSimulator_KAI/blob/2fae104567b8c26029fbf46c49a178f05dd445c1/slotitems.csv

期待する動作としては、while文でcsv一行ずつ処理をしたいのですが、何が問題なのでしょうか?

また、WindowsのMSYS2で実行するとLinuxで実行したときより遥かに多く時間がかかるので、おそらくWindowsにfork()がないためだとは思うのですが、コード中のどの辺が重くなっている要因でしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

何をするスクリプトかよくわからないですが、readwhile readの所と、read -p "Press [Enter] key to start backup..."の所と、2カ所かあるのでそれぞれデータを読み込んでいるのでは?
キー入力したいなら、</dev/ttyとか付けてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/14 19:36

    あ・・・。本当だ。ありがとうございます。

    重くなる原因についてはなにか気がついた点などありますでしょうか?

    キャンセル

  • 2017/01/14 19:49

    時間が掛かるが正常終了するのでしょうか?

    キャンセル

  • 2017/01/14 20:37

    しますね。

    キャンセル

  • 2017/01/14 20:38

    Linuxで1分以内なのに30分近くかかりましたが。

    キャンセル

  • 2017/01/14 21:30

    とりあえず、bash -x でどこで時間が掛かっているのかみるのでしょうか。

    キャンセル

  • 2017/01/15 00:49

    わかりました。
    tmp=$(echo "${e}" | sed -e 's/\//./')
    のようにしていた部分ですが、外部コマンド呼び出しが重かったようです。
    ${elements[$j]//\//.}
    のように変数展開で書き直すことで劇的に高速化できました!

    デバッグ機能便利ですね・・・。

    キャンセル

  • 2017/01/15 00:50

    https://github.com/YSRKEN/KanColleSimulator_KAI/pull/174/commits/14d402898172d8dc2742d88849794541c540a9e6

    キャンセル

同じタグがついた質問を見る

  • bash

    698questions

    bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。