変数[duplicate]に割り当てるとき、最後の改行文字の存在を維持します。

変数[duplicate]に割り当てるとき、最後の改行文字の存在を維持します。

Bashでキャプチャを使用して変数として出力すると、迷惑な$(...)改行文字が追加されます。しかし、私の出力は改行文字で終わる場合もあり、そうでない場合もあります。出力をそのままキャプチャしたいです。

実際の問題では、文字列に複数の行を含めることができますが、最後の行は改行文字で終わらないか、終わらない可能性があるため、このプロパティは維持する必要があります。

スタイルはStack Exchangeへの回答です。、私の最小作業の例は次のとおりです。

#!/bin/bash

newlinetest() {
    if [ "$1" = 'with' ]; then
        printf '%s\n' 'Text with newline'
    else
        printf '%s' 'Text without newline'
    fi
}

s="$(newlinetest with ; printf '%s' 'x')"
s="${s%?}"
printf '%s%s%s\n' '(' "${s}" ')'
s="$(newlinetest without ; printf '%s' 'x')"
s="${s%?}"
printf '%s%s%s\n' '(' "${s}" ')'

やるべきことがありますが、IMHOこれは見苦しいハッキングのようです。この問題を解決する他のエレガントな方法はありますか?たぶん関連してmapfileいるかread?外部ツールを必要としないソリューションは非常に歓迎されます。

ベストアンサー1

実際、コマンドの置換は末尾の改行を削除しますが、追加しません。ただし、後でその変数を印刷するために使用すると、デフォルトではecho1が追加されます。

末尾xのエントリを追加することは少しハッキングされているように見えますが、おそらく最も簡単な方法であり、すべてのシェルで動作します。echo x代替を使用して短くすることができますprintf '%s' 'x'

あなたが言及したので、readBashで次のものを使用することもできます。

IFS= read -rd '' var < <(newlinetest with)

これがこれよりも美しいかどうかを決定させます。

var=$(newlinetest with; echo x)
var=${var%x}

2つの間に潜在的なパフォーマンスの違いがありますが。最初のプロセス置換は、次をread読み取るパイプを生成します。一度に1バイト区切り文字の超過を防ぐために(ここでは重要ではありませんが、シェルはこれを知りません)、コマンド置換はより大きなチャンクから読み取られるため、大きな出力の場合は高速になります。

おすすめ記事