web-dev-qa-db-ja.com

bashスクリプトの変数に改行を追加する方法

私がする時

str="Hello World\n===========\n"

\nもプリントアウトしました。どうすれば改行できますか?

80
Jiew Meng

bashでは、構文を使用できます

str=$'Hello World\n===========\n'

$が前に付いた単一引用符は、文字列にエスケープシーケンスを挿入できる新しい構文です。

また、printf組み込みにより、結果の出力を変数に保存できます

printf -v str 'Hello World\n===========\n'

どちらのソリューションもサブシェルを必要としません。

以下で文字列を出力する必要がある場合は、次の例のように二重引用符を使用する必要があります。

echo "$str"

引用符なしで文字列を印刷すると、改行はスペースに変換されるためです。

90
enzotib

(任意のBourne/POSIXスタイルのシェルでは)リテラルの改行を単一引用符で囲むことができます。

_str='Hello World
===========
'
_

複数行の文字列の場合、 hereドキュメント がしばしば便利です。文字列はコマンドへの入力として供給されます。

_mycommand <<'EOF'
Hello World
===========
EOF
_

文字列を変数に格納する場合は、コマンド置換でcatコマンドを使用します。文字列の最後の改行文字は、コマンド置換によって削除されます。最後の改行を保持したい場合は、最後にストッパーを付けて、後で取り除きます。 POSIX準拠のシェルでは、str=$(cat <<'EOF'); str=${str%a}の後にヒアドキュメントを続けて記述できますが、bashでは、ヒアドキュメントを閉じ括弧の前に置く必要があります。

_str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
_

Ksh、bash、zshでは、_$'…'_引用符付きの形式を使用して、引用符内のバックスラッシュエスケープを展開できます。

_str=$'Hello World\n===========\n'
_

「エコー」を使っていますか? 「echo -e」を試してください。

echo -e "Hello World\n===========\n"
9
Mike

スクリプトで改行が何度も必要な場合は、改行を保持するグローバル変数を宣言できます。そうすれば、二重引用符で囲まれた文字列(変数の展開)で使用できます。

NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
6
pihentagy

既存のすばらしい答えを補足するには:

bashを使用していて読みやすくするために実際の改行を使用するを希望する場合、readhere-doc in a variable、これは(他のソリューションのように)サブシェルの使用を必要としません。

# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF'   # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
  • -rは、readが入力を解釈しないことを保証します(デフォルトでは、バックスラッシュを特別に扱いますが、ほとんど必要ありません)。

  • -d ''は、「レコード」区切り文字を空の文字列に設定し、readentire入力を一度に読み取るようにします(代わりに単一行の)。

$IFS(内部フィールド区切り文字)をデフォルトのままにすることで、$' \t\n'(スペース、タブ、改行)、任意の先頭と末尾の空白がヒアドキュメントの末尾の改行を含む、$strに割り当てられた値からtrimmed
(here-docの本文はafterの後に開始区切り文字('EOF' here)で始まることに注意してください。 ないには行頭改行が含まれます)。

通常、これは望ましい動作ですが、末尾の改行が必要な場合は、IFS= read -r -d ''の代わりにread -r -d ''を使用しますが、any先頭と末尾の空白が保存されます。
IFS= readコマンドの前に直接付加することは、割り当てがそのコマンドの間のみ有効であることを意味するため、以前の値を復元する必要がないことに注意してください。)


Here-docを使用すると、オプションでインデントを使用で複数行の文字列を読みやすくすることができます。

# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
    Hello World
    ===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]

-<<と開始のhere-doc区切り文字('EOF'、here)の間に配置すると、先頭のタブ文字がhere-doc本体と終了の区切り文字からも削除されますが、注意してくださいこれはactualタブ文字でのみ機能するであり、スペースではないため、エディターがタブのキープレスをスペースに変換する場合、追加の作業は必要。

3
mklement0

すべての議論から、これが私にとって最も簡単な方法です:

bash$ str="Hello World
==========="
bash$ echo "$str"
Hello World
===========

echoコマンドは二重引用符を使用する必要があります。

3
kholis