, чтобы решить эту проблему, вы должны хранить данные результата перед ее использованием
$numRecords->execute();
$numRecords->store_result();
, это все
Легким ответом является переадресация после done
, а не на printf
:
for key in "${!array[@]}"; do
value=${array[$key]}
[[ $key = *[$'\t\n']* ]] && continue # security: disallow keys with tabs or newlines
[[ $value = *[$'\n']* ]] && continue # security: disallow values with newlines
printf "%s\t%s\n" "$i" "${array[$i]}"
done >outfile
Обратите внимание на эти проверки - я не делаю их позже в этом коде , но они необходимы, чтобы позволить в вашем формате вводить другие пары ключ / значение или позволять «значениям» фактически указывать другие ключи.
Таким образом, чтобы заменить весь файл сразу , для обеспечения атомарности следует использовать шаблон записи и переименования. Общий шаблон:
tempfile=$(mktemp outfile.XXXXXX)
write_your_data >"$tempfile"
mv -- "$tempfile" outfile
write_your_data
не обязательно должен быть заполнителем - он также может быть функцией, инкапсулирующей сам цикл:
write_your_data() {
local i
for i in "${!array[@]}"; do
printf "%s\t%s\n" "$i" "${array[$i]}"
done
}
Чтобы быть ясным, причина, по которой вы видите только последнюю строку, состоит в том, что вы используете >
вместо >>
.
>
перенаправляет вывод в файл, создавая это или перезапись того, что уже было там.
>>
также перенаправляет вывод, но добавляет его в файл ... добавляет его в конец.
Каждый раз, когда ваш for
повторяется, вы «воссоздаете» файл.
for i in "${!array[@]}"; do
printf "%s\t%s\n" "$i" "${array[$i]}" >> outfile
done
>>
для индивидуальных вызовов printf
или echo
неэффективно: он повторно открывает файл перед записью каждой отдельной строки и снова закрывает его после. Это целая группа open()
s и close()
s (и, следовательно, неявно, флеши), которых можно было бы избежать, если бы вы открыли файл только один раз и повторно использовали этот дескриптор.
– Charles Duffy
22 June 2017 в 19:58