複数行の文字列を1行ずつ繰り返します。

複数行の文字列を1行ずつ繰り返します。

/bin/shBSDプラットフォームのPOSIXシェル()で複数行の文字列を処理し、1行ずつ繰り返したいと思います。 BashはデフォルトのBSDディストリビューションには含まれておらず、GPLに基づいてライセンスされているため、一般的に使用できるように努めています/bin/sh

私はパイプを使って解決策を見つけましたが、通常の/bin/shシェルではこれらの解決策は別々のプロセスとして扱われるので、これはうまくいきません。

MULTILINE="`cat ${SOMEFILE}`"
SOMEVAR="original value"

echo "${MULTILINE}" | while IFS= read -r SINGLELINE
do
 SOMEVAR="updated value"
 echo "this is a single line: ${SINGLELINE}"
 echo "SOMEVAR is now: ${SOMEVAR}"
done

echo "Final SOMEVAR is unchanged: ${SOMEVAR}"

${SOMEVAR}上記の例では、変数の変更(つまり、whileループの外部からアクセスできない)を除いて、私が望むことを行います。

私の質問:この制限なしに同様のことをどのように実行できますか?多くのソリューションにはBashが必要ですが、私は標準のPOSIXシェルを使用しています/bin/sh

ベストアンサー1

ここではマニュアルを使用できます。

while IFS= read -r SINGLELINE
do
  SOMEVAR="updated value"
  printf '%s\n' "this is a single line: ${SINGLELINE}"
  printf '%s\n' "SOMEVAR is now: ${SOMEVAR}"
done << EOF
$MULTILINE
EOF
printf '%s\n' "Final SOMEVAL is still $SOMEVAR"

sh実装に応じて、ここのドキュメントは削除された一時ファイル(シェルが変数の拡張と改行文字を事前に保存する)、またはシェルが変数の拡張とそれに続くパイプを提供するパイプとして実装されます。改行。どちらの場合も、リダイレクトされたコマンドは元のBourneシェル(現在は廃止され、POSIX準拠のシェルではない)以外のサブシェル(POSIXで要求されているように)では実行されません。

または分割+globを使用できます。

IFS='
' # split on newline only
set -o noglob
for SINGLELINE in $MULTILINE
do
  SOMEVAR="updated value"
  printf '%s\n' "this is a single line: ${SINGLELINE}"
  printf '%s\n' "SOMEVAR is now: ${SOMEVAR}"
done
printf '%s\n' "Final SOMEVAL is still $SOMEVAR"

しかし、空行はスキップされます。

おすすめ記事