web-dev-qa-db-ja.com

Bash:各配列メンバーの周りの引用符を取り除くネイティブな方法

別のスクリプトから配列を読み取りました。この配列は" "一部のメンバーが空であるため、すべての配列メンバーの周囲。

in_file=./data
vector=($(./readdata.sh 0 $in_file))
for index in ${!vector[@]}
do
    echo ${vector[index]}
done

問題は、各出力行の周りに引用があり、それらを取り除きたいということです。

"red"
"blue"
"green"
""
"white"
"black"

次のように変更する必要があります。

red
blue
green

white
black

awktrsedまたはその他のパイプラインベースの方法を使用しないメソッドを探しています。かっこ、句読点の違いなど、ネイティブな方法で解決したいだけです。

4
ar2015

これはうまくいくかもしれません:

in_file=./data
vector=($(./readdata.sh 0 $in_file))
for index in ${!vector[@]}
do
    echo ${vector[index]//\"/}
done

参照: http://www.tldp.org/LDP/abs/html/refcards.html#AEN22828

4
FloHimself

readdata.shが余分な引用符なしで改行区切りデータを生成する場合は、プログラムをよりシンプルで堅牢にします。

現在のプログラムでは、readdata.shの出力は空白で分割され(つまり、"a b"は2つの配列要素"ab"になります)、結果の各Wordはワイルドカードパターン(たとえば、"a * b""aになり、次に現在のディレクトリ内のファイル名、最後にb"になります)。詳細については、 シェルスクリプトが空白やその他の特殊文字でチョークするのはなぜですか? を参照してください。

Bashは、改行で区切られたデータを読み取る非常に簡単な方法を提供します: mapfile 組み込み。 bashはサブシェルでパイプラインの右側を実行するので、./readdata.sh 0 "$in_file" | mapfile -t vectorと書くだけではなく、変数をコマンドブロックで使用するか、プロセス置換を使用できます。

in_file=./data
mapfile -t vector < <(./readdata.sh 0 "$in_file")
for index in "${!vector[@]}"
do
  echo "$index: ${vector[index]}"
done

インデックスのみを使用していない場合は、要素のみを使用して、配列を反復する最も簡単な方法は

for element in "${vector[@]}"
do
  echo "$element"
done

あなたはワンライナーを好むので、

vector=("${vector[@]//\"/}")

テキスト置換は配列全体で機能する可能性があることを覚えておいてください。

2
xae

「ハッキーな」検索と置換のソリューションを避けたい場合は、evalを使用するとうまくいくようです。

vector=( $(eval echo ${vector[@]}) )

これにより、シェルはそれらをechoへの引用符付き引数として解釈し、引用符を削除します。もちろん、上の行はまだ空白の問題がありますが、ここで重要なのはevalを使用するという考えです。

1
Peter Remmers