Разделение многострочной строки на массивы в функции

#linux #bash

#linux #bash

Вопрос:

Я пытаюсь разделить многострочную строку на массив в функции. У меня есть две реализации.

 ToArray () {
  local arg1=$1
  local -n arg2=$2
  
  SAVEIFS=$IFS   # Save current IFS
  IFS=$'n'      # Change IFS to new line
  arg2=($arg1) # split to array $names
  IFS=$SAVEIFS   # Restore IFS
}

ToArray3 () {
  local arg1
  local list=()

  local SAVEIFS=$IFS   # Save current IFS
  IFS=$'n'      # Change IFS to new line
  while read arg1; do
    list =("$arg1")
  done
  IFS=$SAVEIFS

  echo "${list[@]}" 
}

#These lines are just to simulate app's output. I have no control over these.
now=$(date -u " %Y-%m-%dT%H:%m.%S 0000")
nl=$'n'
foo="$now [APP/TASK/ValidateTask/0] OUT Test Run Successful.$nl$now[APP/TASK/ValidateTask/0] OUT Test Run UnSuccessful." 

ToArray "$foo" foobarbaz
# foobarbaz=( $(echo "$foo" | ToArray3) )
for (( i=0; i<${#foobarbaz[@]}; i   ))
do
  value=${foobarbaz[$i]}
  echo "$i: $value"
done
  

ToArray работает просто отлично, но я не могу понять, почему ToArray3 не работает. Я уже перепробовал кучу вещей, так что там куча мусора. Кто-нибудь может помочь мне начать ToArray3 работать?

Комментарии:

1. Для этого есть встроенный mapfile (или его псевдоним readarray ).

Ответ №1:

В скрипте 2 ошибки.

Первый находится в функции ToArray3 :

  • в скрипте echo все элементы list в одной строке, не разделенные 'n'

Второй в «основной» функции:

  • скрипт использует автоматический инициализатор списка, не устанавливая IFS 'n' специальный символ. Таким образом, все пространство используется в качестве разделителя.

Правильный сценарий следующий:

   ToArray () {
      local arg1=$1
      local -n arg2=$2
      
      SAVEIFS=$IFS   # Save current IFS
      IFS=$'n'      # Change IFS to new line
      arg2=($arg1) # split to array $names
      IFS=$SAVEIFS   # Restore IFS
    }
    
    ToArray3 () {
      local arg1
      local list=()
    
      local SAVEIFS=$IFS   # Save current IFS
      IFS=$'n'      # Change IFS to new line
      while read arg1; do
        list =("$arg1")
      done
      IFS=$SAVEIFS
      for (( i=0; i<${#list[@]}; i   ))
      do
        echo ${list[$i]}
      done
    }
    
    #These lines are just to simulate app's output. I have no control over these.
    now=$(date -u " %Y-%m-%dT%H:%m.%S 0000")
    nl=$'n'
    
    foo="$now [APP/TASK/ValidateTask/0] OUT Test Run Successful.$nl$now[APP/TASK/ValidateTask/0] OUT Test Run UnSuccessful." 
    SAVEIFS=$IFS   # Save current IFS
    IFS=$'n'      # Change IFS to new line
    #ToArray "$foo" foobarbaz
     foobarbaz=( $(echo "$foo" | ToArray3) )
    IFS=$SAVEIFS
    for (( i=0; i<${#foobarbaz[@]}; i   ))
    do
      value=${foobarbaz[$i]}
      echo "$i: $value"
    done