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

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

新規登録して質問してみよう
ただいま回答率
85.48%
シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Q&A

解決済

2回答

704閲覧

シェルスクリプトで配列の特定文字で分割、ループしたい

退会済みユーザー

退会済みユーザー

総合スコア0

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

0グッド

0クリップ

投稿2022/03/09 09:09

https://www.delftstack.com/ja/howto/linux/split-string-into-array-in-bash/
上記を参考に、シェルスクリプトで特定の文字で分割とループをさせようとしています。

test="p_root=0000000001 p_open=0900 p_close=1800 p_root=0000000002 p_open=0830 p_close=2000" IFS="p_root=" read -r -a ip_array <<< "${test}" for ip in "${ip_array[@]}" do echo "結果" "$ip" done for result_tmp in ${mst_business_hours} do eval ${result_tmp} done echo "ここでのid結果" ${p_root} echo "ここでのnum1結果" ${p_open} echo "ここでのnum2結果" ${p_close}

現状は上記状態なのですが、echoの結果は

結果 結果 結果 結果 結果 結果 結果 結果 0000000001 結果 結果 結果 結果 en 結果 0900 結果 結果 cl 結果 se 結果 1800 0000000002 0830 2000

と表示されます。
p_root=0000000001 p_open=0900 p_close=1800 p_root=0000000002 p_open=0830 p_close=2000

p_root=0000000001 p_open=0900 p_close=1800

p_root=0000000002 p_open=0830 p_close=2000
に分けてそれぞれechoで出力したいのですが、p_rootで分けることもできていない状態です。

test="p_root=0000000001 p_open=0900 p_close=1800 p_root=0000000002 p_open=0830 p_close=2000" IFS="p_root=" read -r -a ip_array <<< "${test}" for ip in "${ip_array[@]}" do echo "ここでのid結果" ${p_root} echo "ここでのnum1結果" ${p_open} echo "ここでのnum2結果" ${p_close} done

とすると
syntax error near unexpected token `done'
というエラーになります。

どうすれば分けてループさせることができるのでしょうか?

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

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

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

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

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

melian

2022/03/09 09:36

IFS は文字単位で作用しますので、IFS="p_root=" としますと、p, _, r, o, t, = の文字の出現位置で分割される事になります。
guest

回答2

0

ベストアンサー

bash

1#!/bin/bash 2 3function callback { 4 read -r p_root param <<<"$2" 5 eval "$param" 6 echo "ここでのid結果" ${p_root} 7 echo "ここでのnum1結果" ${p_open} 8 echo "ここでのnum2結果" ${p_close} 9} 10 11test="p_root=0000000001 p_open=0900 p_close=1800 p_root=0000000002 p_open=0830 p_close=2000" 12mapfile -t -s 1 -c 1 -C callback ip_array <<< "${test//p_root=/$'\n'}"

実行結果

bash

1$ bash p_root.sh 2ここでのid結果 0000000001 3ここでのnum1結果 0900 4ここでのnum2結果 1800 5ここでのid結果 0000000002 6ここでのnum1結果 0830 7ここでのnum2結果 2000

投稿2022/03/09 09:44

編集2022/03/09 10:07
melian

総合スコア19805

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

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

退会済みユーザー

退会済みユーザー

2022/03/10 02:10

ご回答いただきありがとうございます。 ご教授頂いた内容を試してみたのですが、実行結果が ここでのid結果 0000000002 ここでのnum1結果 0830 ここでのnum2結果 2000 となり、前半の内容を出力することができませんでした。
melian

2022/03/10 02:22 編集

例えば以下の様な場合(p_root = の部分にスペースがある)はそうなります。 test="p_root = 0000000001 p_open=0900 p_close=1800 p_root=0000000002 p_open=0830 p_close=2000"
退会済みユーザー

退会済みユーザー

2022/03/10 02:29

新規でファイルを作ってご教授頂いた内容をそのままコピペして実行してみたのですが同じ結果になってしまいました。
melian

2022/03/10 02:30

なるほど。。。それでは mapfile -t -c 1 -C callback ip_array <<< "${test//p_root=/$'\n'}" に変更(-s 1 を除去)するとどうなりますでしょうか?
退会済みユーザー

退会済みユーザー

2022/03/11 02:10

削除したら全て表示されました! ありがとうございます!
guest

0

IFSの意味の理解を間違っています。IFSにセットするのは文字列じゃ無くて1文字の並びです。
IFS="p_root="は、p_root=という文字列で分割するのじゃなくて、
pまたは_またはrまたはoまたはtまたは=のどれかの文字で分割するという意味です。

特定文字列のところで分割するなら、sed等でしょうか。

Bash

1test="p_root=0000000001 p_open=0900 p_close=1800 p_root=0000000002 p_open=0830 p_close=2000" 2 3IFS=$'\t' ip_array=($(echo "$test" | sed 's/p_root=/\t&1/g' )) 4 5for ip in "${ip_array[@]}" 6do 7 echo "結果" "$ip" 8done 9 10for ip in "${ip_array[@]}" 11do 12 eval "$ip" 13 echo "ここでのid結果" ${p_root} 14 echo "ここでのnum1結果" ${p_open} 15 echo "ここでのnum2結果" ${p_close} 16done

後半は何をしたいのか書かれてないので、適当に推測で書いています。

投稿2022/03/09 09:36

編集2022/03/09 09:38
otn

総合スコア84557

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

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

退会済みユーザー

退会済みユーザー

2022/03/10 02:10

ご回答、認識間違いのご指摘をいただきありがとうございます。 また、説明が悪くすみません。 p_root=0000000001 p_open=0900 p_close=1800 p_root=0000000002 p_open=0830 p_close=2000 は p_root=0000000001 p_open=0900 p_close=1800 と p_root=0000000002 p_open=0830 p_close=2000 に分けて、それぞれのまとまりで処理を実行しようとしています。 分けた後はループで1回目は echo "結果" "$ip" echo "ここでのid結果" ${p_root} echo "ここでのnum1結果" ${p_open} echo "ここでのnum2結果" ${p_close} で 0000000001 0900 1800 0000000001 0900 1800 2回目は 0000000002 0830 2000 0000000002 0830 2000 と表示させる様にしたいです。 ご教授頂いた方法で試したところ、p_rootで2つに分かれているというよりはp_root、p_open、p_closeに一個ずつ代入して2回目のp_root、p_open、p_closeで内容を上書きしている様な感じに見えたので少し違うようでした。
otn

2022/03/10 02:42 編集

echoの部分を目的書式になるように調整すれば良いだけだと思います。 > p_rootで2つに分かれているというよりは 分かれてますけど?何を見て分かれてないと思っていますか?
退会済みユーザー

退会済みユーザー

2022/03/11 02:12

すみません、IFSの時点で分かれていました。 その後のやりたかったこととご教授頂いた内容できちんと合わせることができていなかったので上書きしている状態になっていました。 失礼いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問