2011-10-13 5 views
2

私は2日間私の問題を解決するためにSOとgoogleで検索していましたが、私は運がありませんでした。私の問題は、私は配列を持っており、その要素を0で開始し、その要素の値をループスコープ中に変更します。しかし、配列の値をループの外側に出力すると、すべての値が初期値として0になります。ここでbashでグローバル配列を使用するには?

は私のコードです:

Jones,Bill,235 S. Williams St.,Denver,CO,80221,(303) 244-7989 
Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 

注私はif文の内側にechoを入れたときに、それが正しい値を出力していること:

if [ ${lengths[$j]} -le ${#element} ] 
then lengths[$j]=${#element} 
    echo ${lengths[$j]} 
fi 

#!/bin/bash 
# 
# This is a script to reformat CSV files into pretty-formatted txt files. 

clear 

echo 'This is a script to reformat CSV files into pretty-formatted txt files.' 
echo 

# Get number of elements. 
elements=$(cat CSV_File | sed -n 1'p' | tr ',' '\n' | wc -l) 
# "cat CSV_File" for getting text of the file. 
# "sed -n 1'p'" for getting only first line. 
# "tr ',' '\n'" for replacing ',' with '\n'. 
# "wc -l" for getting number of lines (i.e number of elements). 

# Get number of lines. 
lines=$(cat CSV_File | wc -l) 
# "cat CSV_File" for getting text of the file. 
# "wc -l" for getting number of lines. 

# Initiate an array for elements' lengths. 
for ((i=1; $i < (($elements + 1)) ;i++)) 
do lengths[$i]="0" 
done 

# Find tallest element of each column and put the values into 'lengths' array. 
for ((i=1; $i <= $lines ;i++)) 
do 
    j="1" 
    cat CSV_File | sed -n ${i}'p' | tr ',' '\n' | while read element 
    do 
     if [ ${lengths[$j]} -le ${#element} ] 
     then lengths[$j]=${#element} 
     fi 
     ((j++)) 
    done 
done 

echo ${lengths[1]} # It should print 5 not 0 
echo ${lengths[2]} # It should print 4 not 0 
echo ${lengths[3]} # It should print 19 not 0 
echo ${lengths[4]} # It should print 11 not 0 
echo ${lengths[5]} # It should print 2 not 0 
echo ${lengths[6]} # It should print 5 not 0 
echo ${lengths[7]} # It should print 14 not 0 
echo 

... 

、ここではCSV_File内容です

私は何をしていますか?何か不足していますか?

答えて

7

| while read element; do ... doneはサブシェルで実行されているため、サブシェルが終了するとグローバルへの更新は失われます。

解決策の1つは、bashの 'process substitution'を使用してwhileループへの入力をサブシェルで実行することです。参照してください: Reading multiple lines in bash without spawning a new subshell?

+1

この説明とリンクのためにそれほど多くの時間を節約し、私の問題が何であるかを明確にしました –

関連する問題