web-dev-qa-db-ja.com

Bashの継続行

Bash継続行はどのように使用しますか?

私はあなたがこれを行うことができることを理解しています:

echo "continuation \
lines"
>continuation lines

ただし、インデントされたコードがある場合、うまく機能しません。

    echo "continuation \
    lines"
>continuation     lines
130
user880248

これはあなたが望むかもしれないものです

$       echo "continuation"\
>       "lines"
continuation lines

これがエコーする2つの引数を作成し、1つだけが必要な場合は、文字列の連結を見てみましょう。 bashでは、2つの文字列を隣同士に連結して配置します。

$ echo "continuation""lines"
continuationlines

したがって、継続行インデントなしは、文字列を分割する1つの方法です。

$ echo "continuation"\
> "lines"
continuationlines

しかし、インデントが使用される場合:

$       echo "continuation"\
>       "lines"
continuation lines

これはもう連結ではないため、2つの引数を取得します。

インデントしているがすべてのスペースを取得しないで、行を横切る単一の文字列が必要な場合は、継続行を捨てて変数を使用する方法があります:

$ a="continuation"
$ b="lines"
$ echo $a$b
continuationlines

これにより、追加の変数を犠牲にしてコードをきれいにインデントできます。変数をローカルにすれば、それほど悪くないはずです。

139
Ray Toal

ここで<<-HEREターミネータを使用したドキュメントは、インデントされた複数行のテキスト文字列に適しています。ヒアドキュメントから先頭のタブを削除します。 (ただし、ラインターミネータは残ります。)

cat <<-____HERE
    continuation
    lines
____HERE

http://ss64.com/bash/syntax-here.html も参照してください

すべてではなく、いくつかの先頭の空白を保持する必要がある場合は、次のようなものを使用できます

sed 's/^  //' <<____HERE
    This has four leading spaces.
    Two of them will be removed by sed.
____HERE

長い複雑な文字列を多くの行に折り返すために、私はprintfが好きです:

printf '%s' \
    "This will all be printed on a " \
    "single line (because the format string " \
    "doesn't specify any newline)"
25
tripleee

bash array を使用できます

$ str_array=("continuation"
             "lines")

それから

$ echo "${str_array[*]}"
continuation lines

余分なスペースがあります(bashマニュアルの後):

Wordが二重引用符で囲まれている場合、${name[*]}は、IFS変数の最初の文字で区切られた各配列メンバーの値を持つ単一のWordに展開されます

したがって、IFS=''を設定して余分なスペースを取り除きます

$ IFS=''
$ echo "${str_array[*]}"
continuationlines
7
tworec

コマンド引数の一部として長いメッセージを送信する必要があり、行の長さの制限に従う必要がある状況に遭遇しました。コマンドは次のようになります。

somecommand --message="I am a long message" args

これを解決した方法は、メッセージをヒアドキュメントとして移動することです(@tripleeeが提案したように)。しかし、ヒアドキュメントは標準入力になるので、読み直す必要があるので、以下のアプローチを採用しました。

message=$(
    tr "\n" " " <<- END
        This is a
        long message
END
)
somecommand --message="$message" args

これには、$messageを余分な空白や改行なしで文字列定数として正確に使用できるという利点があります。

上記の実際のメッセージ行には、それぞれtab文字がプレフィックスとして付けられており、これは(<<-を使用しているため)ヒアドキュメント自体によって削除されることに注意してください。末尾にはまだ改行があり、スペースでddに置き換えられます。

また、改行を削除しないと、"$message"が展開されたときに改行がそのまま表示されることに注意してください。場合によっては、$messageを囲む二重引用符を削除することで回避策を講じることができますが、メッセージは単一の引数ではなくなります。

2
haridsv

次のようにインデント内で必要に応じて(バックスラッシュを使用せずに)改行で区切るだけで、改行を削除できます。

例:

echo "continuation
of 
lines" | tr '\n' ' '

または、変数定義の場合、改行は自動的にスペースに変換されます。そのため、該当する場合にのみ余分なスペースを取り除きます。

x="continuation
of multiple
lines"
y="red|blue|
green|yellow"

echo $x # This will do as the converted space actually is meaningful
echo $y | tr -d ' ' # Stripping of space may be preferable in this case
1
rjni

どのような種類のリスクを受け入れるか、データをどれだけよく知って信頼しているかに応じて、単純な変数補間を使用できます。

$: x="
    this
    is
       variably indented
    stuff
   "
$: echo "$x" # preserves the newlines and spacing

    this
    is
       variably indented
    stuff

$: echo $x # no quotes, stacks it "neatly" with minimal spacing
this is variably indented stuff
0
Paul Hodges

ただし、インデントされたコードがある場合、うまく機能しません。

    echo "continuation \
    lines"
>continuation     lines

単一引用符で試して、文字列を連結してください:

    echo 'continuation' \
    'lines'
>continuation lines

注:連結には空白が含まれます。

0
mMontu

これはユーザーが求めたものとはまったく異なりますが、複数の行にまたがる長い文字列を作成する別の方法は、次のように段階的に構築することです。

$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World

明らかにこの場合、一度に構築する方が簡単でしたが、このスタイルは非常に軽量で、長い文字列を処理するときに理解できる場合があります。

0
Jon McClung