Как я могу получить целую строку в CSV из первого элемента и поместить его в массив bash? - PullRequest
1 голос
/ 26 января 2020

Я пишу сценарий оболочки и пытаюсь использовать awk, чтобы извлечь целую строку из файла с разделителями-запятыми .csv и вставить его в массив bash. Я могу определить строку по ее первому элементу (который является уникальным), и он должен быть точным, а не частичным.

Я ожидаю, что массив будет заполнен awk, но, похоже, он помещает все это в первый элемент

get_row() {

array=$(awk -F "," -v var="$1" '$1 == var { print }' csv_file )

echo ${array[@]}

}

Я чувствую, что мне нужно поместить al oop куда-нибудь, чтобы заполнить массив, но я не уверен. Заранее спасибо!

ОБНОВЛЕНИЕ

Я использую CSV для хранения имен хостов, IP-адресов, номеров портов оболочки и имен пользователей, чтобы написать оболочку s sh. Я хочу использовать это как базовую функцию для повторного использования, чтобы я мог извлекать всю информацию, которая мне нужна (когда бы она мне не понадобилась) для конкретной c машины, которую я сохранил в моем csv.

hostname,username,ip_address,ssh_port,sync_dir

идея в том, что я уже знаю, что находится в каждом элементе скалярной переменной, и использую его соответствующим образом, что-то вроде (пока не зашло так далеко, этот не рабочий код - просто пример того, чего я пытаюсь достичь)

ssh "$array[2]" -p "$array[3]" -l "$array[1]"

Ответы [ 2 ]

2 голосов
/ 26 января 2020

Вот как сделать то, что вы просили (по крайней мере, bash 4+), учитывая кучу предостережений о том, как заполнен ваш CSV (без встроенных запятых или новых строк в полях, например, см. Что наиболее надежный способ эффективного анализа CSV с помощью awk? ):

$ cat file
a,b,c
d,e,f

$ IFS=, read -r -a array < <(awk -F, -v var='d' '$1 == var' file)

или:

$ readarray -t array < <(awk -F, -v var='d' '$1 == var{gsub(FS,ORS); print}' file)

, любой из которых заполняет array как:

$ declare -p array
declare -a array=([0]="d" [1]="e" [2]="f")

Я бы, вероятно, просто использовал подход read вместо readarray в этом случае, так как вы просто читаете одну строку и вам нужно сделать так, чтобы awk преобразовывал каждую запятую в новую строку, чтобы подход readarray работал.

Таким образом, ваш код станет, например:

get_row() {
    IFS=, read -r -a array < <(awk -F, -v var="$1" '$1 == var' file)

    echo "${array[@]}"
}

get_row 'some_value'
ssh "${array[1]}" -p "${array[2]}" -l "${array[0]}"

или лучше, поскольку для него не требуется, чтобы массив, заполненный в функции, был глобальным:

$ cat tst.sh
#!/bin/env bash

get_row() {
    declare -n arrayName="$1"
    local keyVal="$2"

    IFS=, read -r -a arrayName < <(awk -F, -v var="$keyVal" '$1 == var' file)
}

get_row 'array' 'd'
echo ssh "${array[1]}" -p "${array[2]}" -l "${array[0]}"

$ ./tst.sh
ssh e -p f -l d

или вы можете получить get_row(), просто получить строку и затем заполнить array ее выводом:

$ cat tst.sh
#!/bin/env bash

get_row() { awk -F, -v var="$1" '$1 == var' file; }

IFS=, read -r -a array < <(get_row 'd')
echo ssh "${array[1]}" -p "${array[2]}" -l "${array[0]}"

$ ./tst.sh
ssh e -p f -l d

Как и в большинстве вещей в UNIX, у вас есть много вариантов: -).

0 голосов
/ 26 января 2020

Надеюсь, что ниже поможет вам

Давайте рассмотрим csv_file с данными ниже

# cat csv_file
a,b,c
d,e,f
g,h,i

Назначение вывода awk для переменной с именем "array"

array=$(awk -F "," '{print $1}' csv_file)

где $ 1 представляет номер столбца файла csv

# echo $array
a d g

Этот вывод может быть передан в al oop.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...