Как использовать глобальные массивы в Bash? - PullRequest
2 голосов
/ 13 октября 2011

Я искал в SO и Google решение моей проблемы 2 дня, но мне не повезло.Моя проблема в том, что у меня есть массив, и я инициирую его элементы с нулями, и я изменяю значения его элементов внутри для цикла цикла while.Но когда я печатаю значения массива вне цикла, я нахожу все 0 как их начальные значения !!

Вот мой код:

#!/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:

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

Обратите внимание, что когда я помещаю echo внутри оператора if, он печатает правильное значение:

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

Что не так я делаю?Я что-то упустил?

1 Ответ

7 голосов
/ 13 октября 2011

| while read element; do ... done работает в под-оболочке, поэтому его обновления в глобальном масштабе теряются при выходе из под-оболочки.

Одним из решений является использование «подстановки процессов» в bash для получения входных данных цикла while для запуска в подоболочке.См .: Чтение нескольких строк в bash без появления нового подоболочки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...