Используйте элементы массива в качестве имен переменных, которые я хочу прочитать из файла - PullRequest
0 голосов
/ 07 июня 2018

Я знаю, что чтение файла .csv можно сделать просто в bash с помощью этого цикла:

#!/bin/bash
INPUT=data.cvs
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read flname dob ssn tel status
do
    echo "Name : $flname"
    echo "DOB : $dob"
    echo "SSN : $ssn"
    echo "Telephone : $tel"
    echo "Status : $status"
done < $INPUT
IFS=$OLDIFS

Но я хочу немного изменить это - я хочу, чтобы столбцы были определены программистом в файле bash.Например:

declare -a columns=("Name", "Surname", "ID", "Gender")
while read columns
    do
        //now echo everything that has been read
done < $INPUT

Итак, я хочу указать список переменных, которые должны использоваться в качестве контейнера для чтения данных CSV с помощью массива, а затем получить доступ к этому массиву внутри тела while.
Есть ли способ сделать это?

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Ключом к этому решению является комментарий перед оператором while ниже.read является встроенным, но это все еще команда, а аргументы команды перед ее выполнением расширяются оболочкой.После расширения ${columns[@]} команда становится

read Name Surname ID Gender

Пример:

# Don't use commas in between array values (since they become part of the value)
# Values not quoted because valid names don't need quotes, and these
# value must be valid names
declare -a columns=(Name Surname ID Gender)

Затем мы можем попробовать:

# Read is a command. Arguments are expanded.
# The quotes are unnecessary but it's hard to break habits :)
while read "${columns[@]}"; do
  echo Name is "$Name"
  # etc
done <<< "John Doe 27 M"

Вывод:

Name is John

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

$ columns="Name Surname ID Gender"
$ # Here it is vital that $columns not be quoted; we rely on word-splitting
$ while read $columns; do 
> echo Name is $Name
> done 
John Doe 27 M
Name is John

...
0 голосов
/ 07 июня 2018

Считайте строку в массив, затем выполните цикл по этому массиву и создайте ассоциативный массив, который использует имена столбцов.

while read -r line
do
    vals=($line)
    declare -A colmap
    i=0
    for col in ${columns[@]}
    do
        colmap[col]=${vals[$i]}
        let i=i+1
    done
    # do stuff with colmap here
    # ...
    unset colmap # Clear colmap before next iteration
done < $INPUT
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...