Как я могу добавить в файл из скаляра в bash? - PullRequest
0 голосов
/ 26 февраля 2020

Я пишу функцию, которая будет принимать 2 аргумента - имя скаляра и имя файла и будет записывать скаляр (с разделителем новой строки) в этот файл. Я получаю ошибку "плохая замена". Вот мой код:

#!/bin/bash

arr_to_f() {
for y in "${1[@]}"
       do
       echo "$y" >> "$2"
       done
}

mapfile -t arr < <(echo "one" ; echo "two" ; echo "three")

arr_to_f arr file

Я мог бы сделать это вне функции, используя мой l oop, но я буду часто его использовать, я думаю, так что я скорее смог бы вызвать его, если это возможно.

Ответы [ 2 ]

2 голосов
/ 26 февраля 2020

Вы можете создать именованную ссылку на переменную arr. Я также заменил echo на printf в вашем коде, см. Почему printf лучше, чем echo? .

#!/bin/bash

arr_to_f() {
  local -n myarray=$1
  for y in "${myarray[@]}"; do
    printf '%s\n' "$y"
  done >>"$2"
}

mapfile -t arr < <(printf '%s\n' one two three)
arr_to_f arr file

Вы также можете избавиться от for-l oop в вашей функции:

arr_to_f() {
  local -n myarray=$1
  printf '%s\n' "${myarray[@]}" >>"$2"
}
1 голос
/ 26 февраля 2020

ПРИМЕЧАНИЕ: В этом ответе используется eval, и его следует по возможности избегать. См. ответ Фредди , который использует declare -n / local -n для создания именованной ссылки.

Этот подход может быть необходим, если вы используете старую версию bash.



Как уже указывалось, вы передаете буквенную строку arr, и это не массив, следовательно, " плохая подстановка ".

Вы можете использовать eval для построения строки, которая приведет к расширению до того, что вы ищете:

arr_to_file() {
    local cmd
    printf -v cmd 'local -a _content=( "${%q[@]}" )' "${1}"
    eval "${cmd}"
    printf '%s\n' "${_content[@]}" > "${2}"
}

mapfile -t arr < <(echo "one" ; echo "two" ; echo "three")

arr_to_file arr file

eval обычно получает большое предупреждение, так что вот ваше: " eval очень опасен, если вы не доверяете строке, которую вы ему даете".

Если мы будем очень осторожны с eval, то его можно использовать довольно безопасно. Здесь printf "%q" "${1}" используется для указания первого аргумента, подходящего для ввода в оболочку (например: printf '%q' '}' не будет выделяться из имени переменной). Спасибо Charles Duffy за исправленный и значительно более безопасный и более читаемый фрагмент.

Этот подход также будет работать для ассоциативных массивов (т.е. массивов, которые используют ключи вместо индексов), но вывод будет неупорядоченным.

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