web-dev-qa-db-ja.com

bash forループで生成された文字列から最後のコンマを削除します

配列からコンマ区切りのリストを作成して、ヒアドキュメントに入れ、最後のコンマを削除する必要がある状況を扱っています。私はforにパイプ接続されたbash sedを使用しています。これは、最後のコンマではなくすべてのコンマを消去しています。簡単な例は次のとおりです。

x=$(for i in a b c; do echo "${i}",; done| sed 's/,$//')
echo $x
a b c

望ましい出力:

a, b, c

どんな提案も歓迎します。

6
mkc

問題は、デフォルトで、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
6
John1024

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
9
iruvar

このためのもう1つの便利なテクニックはpaste -s

$ arr=(a b c)
$ printf "%s\n" "${arr[@]}" | paste -sd,
a,b,c

paste -sd,これは非常に一般的な「この改行で区切られたアイテムのセットをコンマ区切りのリストに変換する」操作です)

4
Aaron Davies
$ w=(a b c)

$ IFS=, eval 'echo "${w[*]}"'
a,b,c

余談ですが、ここでは ホイールの再発明 ですか?

1
Steven Penny

lastカンマを絶対に削除する必要があるのはなぜですか?

そもそも問題について正しく考えるのではなく、物事を台無しにして、後で台無しにしようとしています。

コンマを各項目の後ろではなく、各項目の前にあるものとして見ると、解決策があります。

for i in a b c; do
  u="${u:+$u, }$i"
done
echo $u

bashパラメータ置換 を参照してください。

結果:

a, b, c
0
Marki

配列の場合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 

最後の関数を除いて、関数への各引数をポップし、改行なしで", "を追加してエコーします。次に、最後の引数と改行をエコーし​​ます。

0
Scott Leadley

次のスクリプトを確認してください

 $ 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に指示する

0
miracle173