web-dev-qa-db-ja.com

配列の各要素がbashの新しい行にあるファイルに配列を出力する

配列の各要素をファイルの新しい行に入れて、配列の内容をファイルに入れようとしています。

IFS=$'\n'   
echo "${mtches[@]}" > sample1.txt 


mtchesのコンテンツは「qwe」と「asd」です。ただし、sample1.txtファイルにはqwe asdが1行で含まれています。なぜIFSの価値を考慮に入れないのですか?

13
Ashwin

あなた printfの代わりにechoを使用する必要があります

printf "%s\n" "${mtches[@]}"

mtchesが空の場合でも、空の1行が出力されます。それを説明するには:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%s\n' "${mtches[@]}"; } > file

bash(およびPOSIXシェルも)では、特別な理由がない限り、"$@"ではなく Positional Parameters array as"$*"を使用することがよくあります。 通常の配列、man bashからの配列-セクション配列 をサポートするシェルでも同様です。

配列の任意の要素は、$ {name [subscript]}を使用して参照できます。括弧は、シェルのファイル名展開演算子との競合を避けるために必要です。下付き文字が「@」または「*」の場合、Wordは配列名のすべてのメンバーに展開されます。これらの添え字は、Wordが二重引用符で囲まれている場合にのみ異なります。 Wordが二重引用符で囲まれている場合、$ {name [*]}は各配列メンバーの値がIFS変数の最初の文字で区切られた単一のWordに展開され、$ {name [@]}はnameの各要素を展開します別の単語に。配列のメンバーがない場合、$ {name [@]}は何も展開しません。二重引用符で囲まれた展開がWord内で発生する場合、最初のパラメーターの展開は元のWordの最初の部分と結合され、最後のパラメーターの展開は元のWordの最後の部分と結合されます。これは、特別なパラメータ「@」と「*」の拡張に類似しています。

"${array[*]}"は、すべての配列要素を文字列に結合する場合にのみ使用してください。

17
cuonglm

代わりに${mtches[*]}を使用します。

"${mtches[@]}"を使用する場合、$IFSの値が何であるかは関係ありません。bashは配列を複数の引数に分割します。必要なのは、各配列要素を\nで結合した単一の引数です。 ${mtches[*]}がこれを実現します。

また、$IFSを一時的に設定する方法として、次のことができます。

( IFS=$'\n'; echo "${mtches[*]}" > sample1.txt )

そうすれば、それを元に戻すことに煩わされる必要はありません。

7
Patrick

forの使用:

for each in "${alpha[@]}"
do
  echo "$each"
done

history;を使用する値に!が含まれている場合、これは失敗します:

history -p "${alpha[@]}"

basenameを使用します。値に/が含まれている場合、これは失敗します:

basename -a "${alpha[@]}"

shufを使用します。結果が順番に出ない場合があることに注意してください:

shuf -e "${alpha[@]}"
2
Steven Penny
for ENTRY in ${ARRAY[@]}; do
    echo $ENTRY
done > outfile

見やすく、読みやすく、IFSをいじる必要はありません。また、各行の処理をカスタマイズできることも意味します。

1
steveayre