прочитанные строки в массив, один элемент на линию с помощью bash

Думаю, эти переключатели сделают то, что вы хотите с помощью wget:

   -A acclist --accept acclist
   -R rejlist --reject rejlist
       Specify comma-separated lists of file name suffixes or patterns to 
       accept or reject. Note that if any of the wildcard characters, *, ?,
       [ or ], appear in an element of acclist or rejlist, it will be 
       treated as a pattern, rather than a suffix.

   --accept-regex urlregex
   --reject-regex urlregex
       Specify a regular expression to accept or reject the complete URL.

Пример

$ wget -r --no-parent -A 'bar.*.tar.gz' http://url/dir/
1
30.11.2018, 20:21
3 ответа

TL;DR

В баш:

readarray -t arr2 < <(git … )
printf '%s\n' "${arr2[@]}"

По вашему вопросу есть две разные проблемы

  1. Расщепление оболочки.
    Когда вы это сделали:

    arr1=($(git … ))
    

    «расширение команды» не заключено в кавычки, поэтому :оно подлежит разделению оболочки и подстановке.

    Чтобы точно увидеть, что делает это разделение оболочки, используйте printf:

    $ printf '<%s>  '  $(echo word '"one simple sentence"')
    <word>  <"one>  <simple>  <sentence">
    

    Этого можно было бы избежать, цитируя:

    $ printf '<%s>  '  "$(echo word '"one simple sentence"')"
    <word "one simple sentence">
    

    Но это также позволит избежать разбиения на новые строки, которое вы хотите.

  2. Труба
    Когда вы казнили:

    git … | … | … | readarray arr2
    

    Переменная массива arr2была установлена, но исчезла, когда канал(|)был закрыт.

    Вы можете использовать это значение, если остаетесь внутри последней подоболочки:

    $ printf '%s\n' "First value." "Second value." | 
            { readarray -t arr2; printf '%s\n' "${arr2[@]}"; }
    First value.
    Second value.
    

    Но значение arr2не выживет из трубы.

Решение (с)

Вам нужно использовать чтение для разделения на новые строки, но не с вертикальной чертой.
От старого к новому:

  1. Петля.
    Для старых оболочек без массивов (с использованием позиционных аргументов единственный квази-массив):

    set --
    while IFS='' read -r value; do
        set -- "$@" "$value"
    done <<-EOT
    $(printf '%s\n' "First value." "Second value.")
    EOT
    
    printf '%s\n' "$@"
    

    Установить массив (ksh, zsh, bash)

    i=0; arr1=()
    while IFS='' read -r value; do
        arr1+=("$value")
    done <<-EOT
    $(printf '%s\n' "First value." "Second value.")
    EOT
    
    printf '%s\n' "${arr1[@]}"
    
  2. Здесь -строка
    Вместо здесь документа(<<)мы можем использовать здесь -строку (<<<):

    .
    i=0; arr1=()
    while IFS='' read -r value; do
        arr1+=("$value")
    done <<<"$(printf '%s\n' "First value." "Second value.")"
    
    printf '%s\n' "${arr1[@]}"
    
  3. Замена процесса
    В оболочках, поддерживающих (ksh, zsh, bash ), вы можете использовать <( … )для замены здесь -строки:

    i=0; arr1=()
    while IFS='' read -r value; do
        arr1+=("$value")
    done < <(printf '%s\n' "First value." "Second value.")
    
    printf '%s\n' "${arr1[@]}"
    

    С различиями:<( )может выдавать байты NUL, в то время как строка здесь -может удалять (или выдавать предупреждение )NUL. Строка here -по умолчанию добавляет завершающую новую строку. Могут быть и другие AFAIK.

  4. чтение массива
    Используйте readarrayв bash[a](a.k.a mapfile), чтобы избежать петли:

    readarray -t arr2 < <(printf '%s\n' "First value." "Second value.")
    printf '%s\n' "${arr2[@]}"
    

[a]В ksh вам нужно будет использовать read -A,который очищает переменную перед использованием, но нуждается в некоторой «магии», чтобы разделить на новые строки и сразу прочитать весь ввод.

IFS=$'\n' read -d '' -A arr2 < <(printf '%s\n' "First value." "Second value.")

Вам потребуется загрузить модуль mapfileв zsh , чтобы сделать что-то подобное.

13
27.01.2020, 23:11

Когда вы перешли к readarray, вы запустили подоболочку, которая правильно заполнила массив arr2, но затем закрылась. Использовать подстановку процесса в качестве входных данных для readarray:

readarray -t arr2 < <(git...)
4
27.01.2020, 23:11

Ты рядом

Это проблема "имена файлов с пробелами".

По умолчанию разделителем является пробел. Это устанавливается переменной окружения IFS.

Чтобы временно изменить переменную среды, используйте:

ifs_backup=$IFS
IFS=$(echo -en "\n\b")

Затем ваш вывод для этой команды:

for a in "${arr1[@]}"; do echo "$a"; done

будет:

"Directory Name/File B.txt"
"File A.txt"

Для восстановленияIFS:

IFS=$ifs_backup
3
27.01.2020, 23:11

Теги

Похожие вопросы