🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
bash

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

sed

sedとは、POSIX環境のために作られたコマンドラインエディタです。sedは編集スクリプトの指示のもとに複数のファイルを編集し、標準出力にその結果を出力します。

タイムアウト

タイムアウトはイベント発生から完了までに掛かる経過時間に対する一定の待ち時間を指します。また、特定の時間が経過された場合に発生するイベントを指すこともあります。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

Q&A

解決済

3回答

2066閲覧

bashの文字列置換について

blu

総合スコア9

bash

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

sed

sedとは、POSIX環境のために作られたコマンドラインエディタです。sedは編集スクリプトの指示のもとに複数のファイルを編集し、標準出力にその結果を出力します。

タイムアウト

タイムアウトはイベント発生から完了までに掛かる経過時間に対する一定の待ち時間を指します。また、特定の時間が経過された場合に発生するイベントを指すこともあります。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

0グッド

2クリップ

投稿2019/09/13 08:39

編集2019/09/13 08:42

bash

1cat $test1 | 2 sed $(awk '{printf("s/\[%s\]/%s/g;",$1,$2)')}',$test2)

上記のようなコードを書いており、sedとawkを使って文字列の置換をしています。
データの件数としてましては、test1が19752件、test2が1065件です。
特定の文字列のみを置換したいのですが、件数が多くタイムアウトになってしまいます。
※実際はもっと長いソースなのですが、訳ありで記載できません。 ご了承ください。

test1には、数式の中にある[syoukei00]という文字列で(00の部分は可変です。)
test2には、下記のように置換対象文字列と置換後の文字列が入っています。

syoukei00 100 syoukei01 101 syoukei03 102 syoukei04 103

速度を改善したいのですが、早い記述方法などはありますでしょうか?

私なりに色々調べてみたのですが、良く分からなかった為質問させていただきます。
申し訳ありません。
また、bashはほとんど素人同然なので初心者マークをつけさせていただきました。

他に情報が欲しい等ありましたら、記載できる範囲で記載させていただこうと思います。
よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

このような単純な置換処理ならawkでできるので、わざわざsedを組み合わせる必要はないでしょう。

このシェルスクリプトの実行に時間がかかるのは、awkの呼び出してfile2を全部読みする処理をfile1の行数分繰り返しているからと推察されます。これでは、最終的にfile2から19753*1065行分の読み出しを行うことになります。
file2の情報を一回だけ読み込んでスクリプト内に保持しておけば、ディスクアクセスの時間を大幅に減らせます。

awk

1# test.awk 2 3BEGIN{ 4 while((getline < reffile) > 0){ 5 subs["\[" $1 "]"] = $2 6 } 7} 8 9{ 10 for(x in subs){ 11 gsub(x, subs[x]) 12 } 13 print 14}
awk -f test.awk -v reffile=test2 test1

投稿2019/09/13 10:16

KojiDoi

総合スコア13692

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2019/09/13 13:04

> awkの呼び出してfile2を全部読みする処理をfile1の行数分繰り返しているから 1回だけですね。
guest

0

質問文に書いていないところに問題がある可能性が高いです。
どこで時間がかかっているのか、測定してみましょう。

投稿2019/09/13 13:07

otn

総合スコア85893

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

昔、仕事でawkを使って処理していて、量が増えて遅くなってきたのでCで作成したら1~2桁早くなりました。
100~1000行くらいならawkでいいかもしれませんが、10,000行以上あるならばawk(インタープリター系)ではなく、C等コンパイラ系の言語に変更したほうがいいと思います。

投稿2019/09/13 09:25

sage

総合スコア1240

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

blu

2019/09/13 09:35

私もそう思っているんですが、都合上言語を変更できないんです...
sage

2019/09/13 09:57

言語を変えられないのならばcpuを変えるしかないのでは? または、awkのコンパイラを自作し、使用する。
blu

2019/09/13 10:16

すみません、お恥ずかしい話ですがこれは職場での出来事なのです。 なので、言語も、CPUもコンパイラ自作もかないません…。
sage

2019/09/13 10:51

業務上の案件ならば必要性を上司に訴え、高性能のCPUを買ってもらえばいい話では?(コンパイラを注文するとか)
sage

2019/09/13 10:52 編集

タイムアウトしない量に分割して処理するという手もありそうです。
Zuishin

2019/09/13 11:05 編集

そういう問題ではなく、入力の一行毎に awk を呼び出しているのが原因だと思います。 普通なら低評価までしないんですが、高評価が入っていたので下げました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問