配列からコンマ区切りのリストを作成して、ヒアドキュメントに入れ、最後のコンマを削除する必要がある状況を扱っています。私はfor
にパイプ接続されたbash sed
を使用しています。これは、最後のコンマではなくすべてのコンマを消去しています。簡単な例は次のとおりです。
x=$(for i in a b c; do echo "${i}",; done| sed 's/,$//')
echo $x
a b c
望ましい出力:
a, b, c
どんな提案も歓迎します。
問題は、デフォルトで、echo
が呼び出されるたびに新しい行が追加され、sed
がそれらの新しい行で動作していたことです。 bashが$(...)
を処理するときに、これらの新しい行がスペースに変換されるため、これはわかりませんでした。したがって、アプローチに最小限の変更を加えながら問題を修正するには:
$ x=$(for i in a b c; do echo -n "${i}",; done| sed 's/,$//') ; echo $x
a,b,c
オプション -n
は、echo
に新しい行を追加しないように指示します。
アイテム間にスペースが必要な場合は、簡単に追加できます。
$ x=$(for i in a b c; do echo -n "${i}, " ; done| sed 's/, $//') ;echo $x
a, b, c
1つのオプションは、bash
を使用することです
arr=(a b c)
x=$(IFS=,;printf "%s" "${arr[*]}")
echo "$x"
a,b,c
交互に
arr=(a b c)
printf -v x "%s," "${arr[@]}"
x=${x%,}
echo "$x"
a,b,c
2番目のオプションでは、,
だけではなく、区切り文字を,
(コンマの後にスペースが続く)に設定できます。
printf -v x "%s, " "${arr[@]}"
x=${x%, }
echo "$x"
a, b, c
このためのもう1つの便利なテクニックはpaste -s
:
$ arr=(a b c)
$ printf "%s\n" "${arr[@]}" | paste -sd,
a,b,c
(paste -sd,
これは非常に一般的な「この改行で区切られたアイテムのセットをコンマ区切りのリストに変換する」操作です)
$ w=(a b c)
$ IFS=, eval 'echo "${w[*]}"'
a,b,c
余談ですが、ここでは ホイールの再発明 ですか?
lastカンマを絶対に削除する必要があるのはなぜですか?
そもそも問題について正しく考えるのではなく、物事を台無しにして、後で台無しにしようとしています。
コンマを各項目の後ろではなく、各項目の前にあるものとして見ると、解決策があります。
for i in a b c; do
u="${u:+$u, }$i"
done
echo $u
bashパラメータ置換 を参照してください。
結果:
a, b, c
配列の場合a=(1 2 3 4 5)
配列を変更できる場合:
for((i = $(($ {#a [@]}-1)); i-> 0;)); a [i] + = "、";完了 エコー "$ {a [@]}" 1、2、3、4、5
$(( ${#a[@]} - 1 ))
は最後から1つ前の配列インデックスを計算し、a[i]+=","
は文字列を追加します。
関数で実行する場合:
print_with_commas(){ while [[$#-gt 1]]; do echo -n "$ 1、"; shift; done; echo "$ 1" } print_with_commas "$ {a [@]}" 1、2、3、4、5
最後の関数を除いて、関数への各引数をポップし、改行なしで", "
を追加してエコーします。次に、最後の引数と改行をエコーします。
次のスクリプトを確認してください
$ cat run.sh #!/ bin/bash echo example 1 for i in a b c; 「$ {i}」をエコーします。 done echo例2 i for a b c; 「$ {i}」をエコーします。 done | sed '$ s /,//' echo example 3 for i in a b c; 「$ {i}」をエコーします。 done | sed '$!s /$/,/' echo example 4 SEP =' '; for a b c; printf "$ {SEP} $ {i}"; SEP = '、\ n';完了。 printf '\ n' echo example 5 STR = ''; SEP = ''; for a b c; do STR = "$ {STR} $ {SEP} $ {i}"; SEP = ,;完了。 echo $ STR echoの例6 echo 'a、b、c、' || sed 's/^ \(。* \)、\(^、\)* $/\ 1\2 /' echoの例7 echo 'a、b、c、' | sed 's /。\ w * $ //'
次の出力が得られます
$ run.sh 例1 a、 b、 c、 例2 a、 b、 c 例3 a、 b、 c 例4 a、 b、 c 例5 a、b、c 例6 a、b、c 例7 a、b、c
例1:forループは実際に行を生成します。 echo $x
は、これを1行に変換します。
例2:最後の行だけを処理するようにsedに指示できます
例3:最後の行を除くすべてを処理するようにsedに指示できます
例4:初めて実行されるときに特別な処理を行うforループをプログラムできます。行の前に '、\ n'を付けないでください。しかし、多くの場合、最後にいつ実行されたかはわかりません。
例5:例4と同じですが、行を生成せず、単に文字列を生成します
例6:行内の最後の文字列を削除するようにsedに指示する
例7:行の最後の空白以外の文字を削除するようにsedに指示する