Нужна помощь в преобразовании CSV в переменные. Я пробовал использовать IFS, но, похоже, вам нужно определить количество полей. Мне нужно что-то, что может обрабатывать различное количество полей.
* Я изменяю свой исходный вопрос с помощью текущего кода, который я использую (взятого из ответа, предоставленного hschou), который включает обновленные имена переменных с использованием типа вместо строки, раздела и т. Д.
Я уверен, что вы можете сказать это по моему коду, но я довольно зеленый в написании сценариев, поэтому мне нужна помощь, чтобы определить, следует ли и как мне добавить еще один цикл или использовать другой подход к синтаксическому анализу данных typeC, потому что хотя они следуют одному и тому же формату, есть только одна запись для каждого из данных типа A и типа B, и может быть от 1 до 15 записей для данных типа C. Целью является всего 3 файла, по одному для каждого типа данных.
Формат данных:
Контейнер: PL [1-100]
Тип A: [1-20]. [1-100]. [1-1000]. [1-100] - [1-100]
ТипB: [1-20]. [1-100]. [1-1000]. [1-100] - [1-100]
TypeC (от 1 до 15 записей): [1-20]. [1-100]. [1-1000]. [1-100] - [1-100]
* В CSV нет заголовка, но если бы они были, это выглядело бы так (данные контейнера, typeA и typeB всегда находятся в позициях 1,2,3, а данные typeC - все, что следует за этим): Container, typeA, typeB, typeC, tycpeC, typeC, typeC, typeC , ..
CSV: PL3,12.1.4.5-77,13.6.4.5-20,17.3.577.9-29,17.3.779.12-33,17.3.802.12-60,17.3.917.12-45,17.3.956.12-63,17.3.993.12-42 PL4,12.1.4.5-78,13.6.4.5-21,17.3.577.9-30,17.3.779.12-34 PL5,12.1.4.5-79,13.6.4.5-22,17.3.577.9-31,17.3.779.12-35,17.3.802.12-62,17.3.917.12-47 PL6,12.1.4.5-80,13.6.4.5-23,17.3.577.9-32,17.3.779.12-36,17.3.802.12-63,17.3.917.12-48,17.3.956.12-66 PL7,12.1.4.5-81,13.6.4.5-24,17.3.577.9-33,17.3.779.12-37,17.3.802.12-64,17.3.917.12-49,17.3.956.12-67,17.3.993.12-46 PL8,12.1.4.5-82,13.6.4.5-25,17.3.577.9-34
Код:
#!/bin/bash
#Set input file
_input="input.csv"
# Pull variables in from csv
# read file using while loop
while read; do
declare -a COL=( ${REPLY//,/ } )
echo -e "containerID=${COL[0]}\ntypeA=${COL[1]}\ntypeB=${COL[2]}" >/tmp/typelist.txt
idx=1
while [ $idx -lt 10 ]; do
echo "typeC$idx=${COL[$((idx+2))]}" >>/tmp/typelist.txt
let idx=idx+1
#whack off empty variables
sed '/\=$/d' /tmp/typelist.txt > /tmp/typelist2.txt && mv /tmp/typelist2.txt /tmp/typelist.txt
#set variables from temp file
. /tmp/typelist.txt
done
sleep 1
#Parse data in this loop.#
echo -e "\n"
echo "Begin Processing for $container"
#echo $typeA
#echo $typeB
#echo $typeC
#echo -e "\n"
#Strip - from sub data for extra parsing
typeAsub="$(echo "$typeA" | sed 's/\-.*$//')"
typeBsub="$(echo "$typeB" | sed 's/\-.*$//')"
typeCsub1="$(echo "$typeC1" | sed 's/\-.*$//')"
#strip out first two decimils for extra parsing
typeAprefix="$(echo "$typeA" | cut -d "." -f1-2)"
typeBprefix="$(echo "$typeB" | cut -d "." -f1-2)"
typeCprefix1="$(echo "$typeC1" | cut -d "." -f1-2)"
#echo $typeAsub
#echo $typeBsub
#echo $typeCsub1
#echo -e "\n"
#echo $typeAprefix
#echo $typeBprefix
#echo $typeCprefix1
#echo -e "\n"
echo "Getting typeA dataset for $typeA"
#call api script to pull data ; echo out for test
echo "API-gather -option -b "$typeAsub" -g all > "$container"typeA-dataset"
sleep 1
echo "Getting typeB dataset for $typeB"
#call api script to pull data ; echo out for test
echo "API-gather -option -b "$typeBsub" -g all > "$container"typeB-dataset"
sleep 1
echo "Getting typeC dataset for $typeC1"
#call api script to pull data ; echo out for test
echo "API-gather -option -b "$typeCsub" -g all > "$container"typeC-dataset"
sleep 1
echo "Getting additional typeC datasets for $typeC2-15"
#call api script to pull data ; echo out for test
echo "API-gather -option -b "$typeCsub2-15" -g all >> "$container"typeC-dataset"
sleep 1
echo -e "\n"
done < "$_input"
exit 0
Скорость не вызывает беспокойства, но если я сделал что-то действительно глупое там, не стесняйтесь дать мне пощечину правильное направление. :)
В этом сценарии строка просто считывается в переменную по умолчанию $REPLY
. Затем замените запятую пробелом ${REPLY//,/ }
и поместите в массив declare -a COL=()
. Затем часть раздела обрабатывается циклом, в котором индекс столбца вычисляется с помощью$((idx+2))
:
#! /bin/bash
while read; do
declare -a COL=( ${REPLY//,/ } )
echo -e "container=${COL[0]}\nrow=${COL[1]}\nshelf=${COL[2]}"
idx=1
while [ $idx -lt 10 ]; do
echo "section$idx=${COL[$((idx+2))]}"
let idx=idx+1
done
done
Я бы использовал один ассоциативный массив для каждой записи csv :предполагая, что ваши данные были в файле с именемinput.csv
#!/usr/bin/env bash
counter=1 # provides index for each csv record
while read
do
IFS=',' a=( $REPLY ) # numeric array containing current row
eval "declare -A row$counter" # declare an assoc. array representing
# this row
eval "row$counter+=( ['row']=${a[0]} )"
a=( "${a[@]:1}" )
eval "row$counter+=( ['shelf']=${a[0]} )"
a=( "${a[@]:1}" )
eval "row$counter+=( ['section1']=${a[0]} )"
a=( "${a[@]:1}" )
eval "row$counter+=( ['section2']=${a[0]} )"
a=( "${a[@]:1}" )
eval "row$counter+=( ['section3']=${a[0]} )"
a=( "${a[@]:1}" )
eval "row$counter+=( ['section4']=${a[0]} )"
a=( "${a[@]:1}" )
eval "row$counter+=( ['section5']=${a[0]} )"
a=( "${a[@]:1}" )
eval "row$counter+=( ['section6']=${a[0]} )"
a=( "${a[@]:1}" )
declare -p row$counter
(( counter = counter + 1 ))
done < <( cat input.csv )
# access arbitrary element
printf "\n---------\n%s\n" ${row3["section4"]}
это дает мне результат, подобный:
declare -A row1='([section6]="6" [section5]="5" [section4]="4" [section3]="4" [section2]="2" [section1]="1" [shelf]="12" [row]="PL3" )'
declare -A row2='([section6]="" [section5]="" [section4]="" [section3]="2" [section2]="1" [section1]="4" [shelf]="13" [row]="PL4" )'
declare -A row3='([section6]="" [section5]="" [section4]="3" [section3]="2" [section2]="1" [section1]="5" [shelf]="14" [row]="PL5" )'
declare -A row4='([section6]="5" [section5]="4" [section4]="3" [section3]="2" [section2]="1" [section1]="6" [shelf]="15" [row]="PL6" )'
declare -A row5='([section6]="5" [section5]="4" [section4]="3" [section3]="2" [section2]="1" [section1]="7" [shelf]="16" [row]="PL7" )'
declare -A row6='([section6]="5" [section5]="4" [section4]="3" [section3]="2" [section2]="1" [section1]="8" [shelf]="15" [row]="PL8" )'
declare -A row7='([section6]="5" [section5]="4" [section4]="3" [section3]="2" [section2]="1" [section1]="7" [shelf]="16" [row]="PL9" )'
---------
3