
Я использую оболочку bash на CentOS 7. Я хочу запустить запрос MySQL из скрипта оболочки и перебрать каждую строку результатов. Если бы было возвращено 4 строки, я подумал, что мог бы захватить четыре строки в массиве следующим образом:
query="select p.id, p.ebook_id, es.id FROM ...";
echo "$query" > /tmp/query.sql
mysql -u user --password=pass db_id < /tmp/query.sql > /tmp/query.csv
linesIN=`cat /tmp/query.csv | sed 's/\t/,/g'`
arraylength=${#linesIN[@]}
echo $arraylength
Однако $arraylength
всегда выводит 1
, хотя я вижу несколько возвращенных строк результатов. Как мне изменить вышеприведенное, чтобы правильно создать массив результатов, где каждый элемент в массиве представляет одну строку из набора результатов?
решение1
С--batch
вариант, mysql
должен вывести результат по одной записи в строке, а столбцы разделены табуляцией. Вы можете прочитать строки в массив с помощьюБашаmapfile
и подстановка процесса, или подстановка команды и назначение массива:
mapfile results < <( mysql --batch ... < query.sql )
или
set -f # disable globbing
IFS=$'\n' # set field separator to NL (only)
results=( $(mysql --batch ... ) )
(Обратите внимание, что IFS
после этого изменения останутся, а подстановка будет отключена.)
Затем, если вы хотите разделить столбцы строки на некоторые переменные:
IFS=$'\t' read -r col1 col2 col2 ... <<< "${results[0]}"
Ваше задание
linesIN=`cat /tmp/query.csv | sed 's/\t/,/g'`
не являетсяназначение массива(скобки отсутствуют). Он просто присваивает вывод подстановки команды обычной строковой переменной. (Все новые строки будут встроены туда, но это все равно будет одна строка.) ${#linesIN[@]}
все еще работает, поскольку в Bash/ksh одноэлементные массивы и скалярные переменные действуют одинаково.
решение2
Другой способ сделать это — передать вывод команды в цикл while. Обратите внимание, что вы хотите включить -N, иначе результаты будут включать имя столбца.
#!/bin/bash
#Script to read output from a mysql command line by line
mysql -uroot -p example -N -e "select column from table" | while IFS= read -r loop
do
echo "$loop"
done
А если вам нужен просто подсчет, вы сделаете это select count(columnName)
и распечатаете результаты.
решение3
Если вам нужно количество строк в файле, которое будет равно количеству строк, возвращенных запросом, просто используйте wc
для подсчета количества строк в файле
arraylength=$( wc -l < /tmp/query.csv)
echo $arraylength