私がする時
str="Hello World\n===========\n"
私も\n
印刷されます。どうすれば改行ができますか?
私がする時
str="Hello World\n===========\n"
私も\n
印刷されます。どうすれば改行ができますか?
回答:
でbash
構文を使用できます
str=$'Hello World\n===========\n'
a $
で始まる単一引用符は、文字列にエスケープシーケンスを挿入できる新しい構文です。
また、printf
ビルトインにより、結果の出力を変数に保存できます
printf -v str 'Hello World\n===========\n'
どちらのソリューションもサブシェルを必要としません。
以下で文字列を印刷する必要がある場合は、次の例のように二重引用符を使用する必要があります。
echo "$str"
引用符なしで文字列を印刷すると、改行がスペースに変換されるためです。
str=$'Hello World\n===========\n'
呼ばれますか?変数置換?
str=$"My $PET eats:\n$PET food"
?このアプローチは二重引用符で機能します
リテラルの改行を一重引用符で囲むことができます(Bourne / POSIXスタイルのシェルで)。
str='Hello World
===========
'
複数行の文字列の場合、here文書はしばしば便利です。文字列はコマンドへの入力として供給されます。
mycommand <<'EOF'
Hello World
===========
EOF
文字列を変数に保存する場合cat
は、コマンド置換でコマンドを使用します。文字列の末尾の改行文字は、コマンド置換によって削除されます。最終的な改行を保持したい場合は、最後にストッパーを付けて、後で取り除きます。POSIX準拠のシェルでは、str=$(cat <<'EOF'); str=${str%a}
適切なheredocを続けて記述できますが、bashでは、閉じ括弧の前にheredocが必要です。
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
ksh、bash、zshでは、$'…'
引用符で囲まれた形式を使用して、引用符内のバックスラッシュエスケープを展開できます。
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
そのままでは動作しません。.. )
ニーズがエンドの-docの後に次の行に配置するEOF
..しかし、たとえそうであっても、それはコマンドによる末尾の改行を失います置換。
\n
インスタンスを保持するには、ストッパーアプローチの代替手段としてbash
検討IFS= read -r -d '' str <<'EOF'...
してください(私の回答を参照)。
「エコー」を使用していますか?「echo -e」を試してください。
echo -e "Hello World\n===========\n"
echo
-nを指定しない限り、最後の\ n は自動的に追加されるため、最後の\ nは必要ありません。(ただし、問題の主な問題は、これらの改行を変数に入れる方法です)。
bash
、echo -e
ん OS X上で動作する-ためですecho
、bashのある組み込み(むしろ外部実行可能ファイルより)、その組み込みがサポートしています-e
。(組み込みとして、それは上で動作する必要があり、すべてのbashが稼働プラットフォーム;ちなみに、echo -e
で動作ksh
し、zsh
あまりにも)。ただし、対照的に、 OS Xの外部echo
ユーティリティは/bin/echo
-をサポートしていません-e
。
スクリプトで改行を何度も必要とする場合、改行を保持するグローバル変数を宣言できます。そうすれば、二重引用符で囲まれた文字列(変数展開)で使用できます。
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
サブシェルが必要なのですか?
"My dog eats:${NL}dog food"
既存の優れた答えを補完するには:
あなたが使用している場合bash
、あなたが好む読みやすくするために、実際の改行を使用して、read
ために別のオプションである変数にここ-docのキャプチャサブシェルの使用を必要としない(ここでは他のソリューションなど)、。
# 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 ''
「レコード」区切り文字を空の文字列に設定し、入力全体を(1行だけでなく)一度read
に読み取ります。
$IFS
(内部フィールド区切り文字)をデフォルト$' \t\n'
(スペース、タブ、改行)のままにしておくと$str
、ヒアドキュメントの末尾の改行を含むに割り当てられた値から先頭および末尾の空白が削除されることに注意してください。
(here-docの本文は開始区切り文字(ここ)の後の行から始まりますが、先頭の改行は含まれ'EOF'
ていません)。
通常、これは望ましい動作ですが、末尾の改行が必要な場合IFS= read -r -d ''
は、justの代わりに使用しますが、先頭および末尾の空白は保持さread -r -d ''
れることに注意してください。
(コマンドの前に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-docの本文から、さらには区切り記号からも削除されますが、スペースではなく実際のタブ文字でのみ機能することに注意してください。エディターは、タブキーをスペースに変換します。追加の作業が必要です。
次のように行う必要があります。
STR=$(echo -ne "Hello World\n===========\n")
更新:
フレッドが指摘したように、この方法で末尾の「\ n」を失うことになります。バックスラッシュシーケンスを展開して変数を割り当てるには、次のようにします。
STR=$'Hello World\n===========\n\n'
テストしてみましょう:
echo "[[$STR]]"
今私たちに与えます:
[[Hello World
===========
]]
$ ''は$ ""とは異なることに注意してください。2番目は、現在のロケールに従って翻訳を行います。詳細については、「QUOTING」セクションを参照してくださいman bash
。
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
出力:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
か?$(printf %s "$foo")
末尾の改行文字がある$foo
場合、それをトリミングします。