Я пытаюсь написать bash-скрипт для автоматизации установки моих пакетов. Таким образом, идея состоит в том, чтобы прочитать файл .csv (packages.csv) следующим образом:

pkg,Description,option
wget,file downloader,on
curl,tool to transfer data from or to a server,on
nano,text editor for Unix-like computing systems,off
emacs,An extensible customizable free/libre text editor — and more,on

построить массив для каждого столбца (без заголовка), а затем передать массивы в контрольный список диалога.

#!/bin/bash

input="packages.csv"
while IFS=',' read -r col1 col2 col3
do 
    for a in $col1; do
        array_col1+=("$a") 
    done

    for b in $col2; do
        array_col2+=("$b")
    done

    for c in $col3; do
        array_col3+=("$c")
    done        

done < "$input"

array1=("${array_col1[@]:1}")
array2=("${array_col2[@]:1}")
array3=("${array_col3[@]:1}")

let num=${#array2[*]}-1

for i in $(seq 0 $num); do
    list[i]=$(echo ${array1[i]} ${array2[i]} ${array3[i]})
done

OPTION=$(dialog --checklist "Choose packages:" \
10 60 4 \
${list[*]})
exitstatus=$?
if [ $exitstatus = 0 ]; then
    echo "$OPTION"
else
    echo "Cancel"
fi

В какой-то момент я все заработал, но в описании не было пробелов. После того, как я сделал некоторые изменения, чтобы включить пробелы, это не работает вообще. Как я могу это исправить? На самом деле в моем файле .csv у меня более 3 столбцов, но контрольный список bash ожидает 3 аргумента. Можно ли как-то включить их в контрольный список?

1 ответ1

1
#!/bin/bash

input="packages.csv"
while IFS=',' read -r col1 col2 col3 dummy
do
   array+=("$col1")
   array+=("$col2")
   array+=("$col3")
done < <(tail -n +2 "$input")

option=$(dialog --checklist --output-fd 1 "Choose packages:" 10 60 4 "${array[@]}")

exitstatus=$?
if [ $exitstatus = 0 ]; then
    echo "$option"
else
    echo "Cancel"
fi

Основные изменения:

  • tail -n +2 "$input" для удаления заголовка;
  • dummy переменная, позволяющая использовать более трех столбцов (дополнительные столбцы не имеют значения для dialog);
  • одна переменная array для создания входных данных для dialog вместо многих, которые передают данные ограниченным образом;
  • "${array[@]}" как правильный способ передачи массива в качестве аргументов командной строки в этом случае;
  • --output-fd 1 объяснено в этом ответе (там есть лучшие, более надежные решения);
  • строчные переменные в этом ответе.

На самом деле в моем файле .csv у меня более 3 столбцов, но контрольный список bash ожидает 3 аргумента. Можно ли как-то включить их в контрольный список?

Зачем? Правда, dialog --checklist ожидает их три на три. Держите это в порядке. Я думаю, может быть, вам нужно больше столбцов для вашего кода, который идет после dialog . Учтите это: когда dialog успешно возвращает идентификаторы из первого столбца, и у вас есть их в $option , проанализируйте его вывод следующим образом:

for package in $option; do … ; done

(Для этого ваш первый столбец в packages.csv не может содержать пробелов и т.д.)

Таким образом, вы можете сделать что-то для каждого выбранного пакета. Внутри этого цикла вы можете прочитать столько столбцов, сколько вам нужно, но сначала grep для правильной строки:

IFS=',' read -r col1 col2 col3 col4 col5 col6 dummy < <(grep "^${package}," "$input")

(Подсказка: исследуйте read -a , смотрите help read). А затем, все еще внутри цикла, сделайте остальную часть своей работы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .