IFSを異なる値に設定する配列の作成

IFSを異なる値に設定する配列の作成

配列を構成してこの形式でファイルに書き込もうとします。つまり、ファイルの内容は次のようになります。

hero_pairscore=( askdjfh sdf,sdlkfj lksf,dfgdf,dsflkgj,asdlkf ....)

ここで要素はで区切りますcomma。これを行うには、次のコードを書きました。

#!/bin/bash
#set -x

hero_pairscore=()
while read line
do

$( IFS=",";hero_pairscore+=( "$line" )
done < true_pairscore.txt

echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt

ただし、生成されたファイルにはこの内容のみが含まれていますhero_pairscore=( )。私のコードには何の問題があり、必要な出力を提供するにはどうすればよいですか?

答え1

ここでやるべきことは次のとおりです。

  1. 変数を設定します。私達はこれを使用します:

    var="kijhg, fbjhku,,,ioy  fbjfr, kjmyhg"
    
  2. ファイル名拡張の設定$IFSと防止:

    IFS=, ; set -f
    
  3. set出力するシェル配列$@

    set -- $var
    
  4. 親シェル$IFSとシェルパラメータをリセットします。

    unset IFS ; set +f
    
  5. 長く生きる!複数の繰り返しや空白なども保存します!

    printf %s\\n "$@"
    

    出力

    kijhg
     fbjhku
    
    
    ioy  fbjfr
     kjmyhg
    

とにかく私の言葉を聞いてください。 a以外のすべての文字は,保持されます。

切り替える

具体的には、bash配列の代わりに実際のシェル配列を使用することをお勧めします。なぜならすぐにスプリッタに変換できるからです。

printf %s "$*"

#OUTPUT#
kijhg  fbjhku   ioy  fbjfr  kjmyhg %

IFS=, ; printf %s "$*"

#OUTPUT#
kijhg, fbjhku,,,ioy  fbjfr, kjmyhg

$*最初の文字では、シェルの位置引数配列を分割する特別なPOSIX指定品質により、$IFS大量のデータを簡単に変換できます。"quote"パラメータ配列を保護しながら、必要な単一文字に分割できます。最初にちゃんとしたらいいです。

追加/プレフィックス

POSIXはまた、そのための特別な属性を指定します"$@""$1"... eval "\${$#}"各引数のアドレッシング形式に加えて、引数"$@"(引用されている場合)はset現在の値に関係なく最後の引数であるため、すべてのシェル引数に安全に拡張できます。$IFS.したがって、配列の先頭にリストを追加するには、次のようにします。

set -- $list "$@"

頭部/尾方向:

set -- $head "$@" $tail

配列を3倍に増やすには:

set -- "$@" "$@" "$@"

現在の合計

データフローが非常に大きくない限り、次のタスクは現在のタスクより少し速くなる可能性があります。(ただし、ファイルを扱う場合は、シェルの分割を完全に避けるのが最善です):

( set -f -- ; IFS=, ; while read -r line ; do set -- "$@" $line ; done
printf %s "$*" ) | cat >out

たぶんTR?

しかし、私が理解していないことは - あなたは何をしていますか?改行文字をカンマに置き換えますか?私の言葉は -データはすでに改行文字以外にカンマで区切られていますか?もしそうなら、

tr '\n' ',' <in >out

答え2

私がしなければならないことをしなさい考えるあなたがやろうとしているのは、コンマで区切られた各フィールドをtrue_pairscore.txt配列変数として読み取ることです。コードには大きな問題はありません。その行$(の先頭がIFS明らかに間違っているため、スクリプトにエラーが発生します(おそらくこれが出力がない理由です)。それ以外のコードの主な修正は、単語分割を$lineしたいので、引用符を削除することです(通常これを防ぐために使用します)。bashIFS

#!/bin/bash

set -o noglob
OIFS=$IFS
IFS=","
hero_pairscore=()

while IFS= read -r line
do
  hero_pairscore+=( $line )
done < true_pairscore.txt

echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt

set +o noglob
IFS=$OIFS

ただし、上記の操作を2行だけ行う方法は次のとおりです。

IFS=$',\n' read -ra hero_pairscore -d '' <true_pairscore.txt
echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt

修正する

embed.txt他のシェルからファイルをインポートするには、配列に書き込まれた各要素をbash引用する必要があります。hero_pairscoreこれを行うには、echo "hero_pairscore=( ${hero_pairscore[@]} )"次のように置き換えます。

echo "hero_pairscore=( $(printf '"%s" ' "${hero_pairscore[@]}") )"

関連情報