区切り文字とスペースで区切られたファイルの各行を読み取る方法

区切り文字とスペースで区切られたファイルの各行を読み取る方法

私はテキストファイルからいくつかの値を取得し、それをforループに入れて変数として使用する小さなシェルスクリプトを作成しました。これをwsadminコマンドへの入力として使用します。以下は私が書いたシェルスクリプトです。

FILE=`cat test.txt`

for i in `echo "$FILE"`

do
DS_NAME=`echo "$i"|awk -F"=" '{print $2}'`
HOST_NAME=`echo "$i"|awk -F"=" '{print $2}'`
PORT_NUMBER=`echo "$i"|awk -F"=" '{print $3}'`
DB_NAME=`echo "$i"|awk -F"=" '{print $4}'`

echo "$DS_NAME"

echo "$HOST_NAME"

echo "$PORT_NUMBER"

echo "$DB_NAME"

done

私のtest.txtファイルの内容は次のとおりです。

test connection data source=test.connect.com=1234=testdb
test connection data source=test1.connect.com=1134=test1db
test connection data source=test2.connect.com=1234=test2db

シェルスクリプトを実行すると、次のような出力を探しています。

test connection data source
test1.connect.com
1234
testdb

しかし残念ながら、必要なものを手に入れることができませんでした。これはDS_NAMEの単語の間にスペースがあるためだと思います。この問題をどのように解決できますか?どんな提案でもお願いします。

答え1

FILE=`cat test.txt`ファイルの内容(末尾の改行を除く)を変数に保存しますFILE。次に、echo "$FILE"ファイルの内容を印刷します(ダッシュで始まらず、バックスラッシュを含まないと仮定)。自分で書くのは簡単です。

for i in `cat test.txt`

次に、単語分離を可能にするコンテキスト内のコマンド置換は、コマンド出力を行では`…`なく単語に分割する。 (これはデフォルトであり、変更される可能性がありますが、問題を解決するための最良の方法ではありません。)表示される問題は次のとおりです。ループは各行に対して1回実行されるのではなく、各単語に対して1回実行されます。さらに、これらの単語はシェルワイルドカードパターンとして扱われます。test * source=a=b=c次の行がある場合は、*現在のディレクトリのファイル名のリストに置き換えられます。

awkを使用して行からフィールドを抽出するのはうまくいきますが(の破損を除くecho)、複雑すぎて遅すぎます。

1行を読み取り、それをフィールドに分割できるシェル組み込み関数があります。read。ただそれを使用してください。文字をフィールド区切り文字として使用するには、コマンドの=変数を設定します。行末のバックスラッシュを連続した行を表すものとして扱わない場合は、このオプションを渡します。IFSread-rread

while IFS='=' read -r DS_NAME HOST_NAME PORT_NUMBER DB_NAME ignored; do
done <test.txt

追加変数は、ignored追加フィールドがある場合にパーサーをより強力にします。

test connection data source=test.connect.com=1234=testdb=hey, a new field

関連情報