Как расширить этот селектор столбца 2 awk с помощью параметра Bash $1?

Как расширить этот селектор столбца 2 awk с помощью параметра Bash $1?

Я пытаюсь сделать свой скрипт bash функцией с входным параметром Bash, но синтаксис AWK вызывает проблему. Исходный код AWK

http://stackoverflow.com/a/19602188/54964
awk -F "\"*,\"*" '{print $2}' textfile.csv

Псевдокод с параметром Bash$1

file=$(awk -v colN="$1" -F "\"*,\"*" '{print $"${colN}"}' "${input}") 
# http://stackoverflow.com/a/19602188/54964 
# http://stackoverflow.com/a/19075707/54964

Проблема в части print $"${colN}".

Текущий вывод не захватывает второй столбец и занимает всю строку и т.д.

-0.21,-0.245
-0.205,-0.22

Использование только этого столбца print $colNневерно, поскольку всегда берется первый столбец независимо от значения в $1.

Пример варианта использования, где я вызываю его с помощью bash code.bash 2; или полный скриптздесьчто работает, если вы не задаете жестко, какой столбец выбрать (1/2) во всех двухстолбцовых CSV-файлах для объединенного результата вторых столбцов

#!/bin/bash
ids=(101 118 201)
dir="/home/masi/Documents/CSV/"
index=0
for id in "${ids[@]}";
do
        input=$(echo "${dir}P${id}C1.csv")
        # take second column of the file here
        file=$(awk -v colN="$1" -F "\"*,\"*" '{print $colN}' "${input}") # http://stackoverflow.com/a/19602188/54964 # http://stackoverflow.com/a/19075707/54964

        Ecgs[${index}]="${file}"
        index=$index+1
done

Входные данные многостолбцовый 1.csv 2.csv 3.csv

-0.21,-0.245
-0.205,-0.22

Wanted output

101,118,201
-0.245,-0.245,-0.245
-0.22,-0.22,-0.22

ОС: Debian 8.5
Bash 4.30

решение1

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

cut -d, -f2 input.csv | paste -d, - - -

Конечно, это не работает для реальных входных данных, только для ваших примерных входных данных. (Поработайте над улучшением ваших примерных входных/выходных данных для этого типа вопросов, это помогаетмного.)


Если мы сделаем предположения, что:

  • У вас всегда есть ровно три входных файла
  • Называется input1.csv, input2.csv,input3.csv
  • С ровно двумя столбцами каждый
  • И вам нужен второй столбец из каждого файла

Проще всего это сделать с помощью комбинации Awk и paste(и подстановки файлов оболочки):

paste -d, input[123].csv | awk -F, -v OFS=, '{print $2, $4, $6}'

Если эти предположения неверны, вините в этом плохие примеры ввода/вывода. ;)

решение2

Чтобы ответить на ваш вопрос, как указано, учитывая

$ cat file
a,b,c
d,e,f
g,h,i
j,k,l

и простой тестовый сценарий

$ cat col.bash
#!/bin/bash

awk -F, -vcol="$1" '{print $col}' file

вы можете проверить, что $colдействительно ссылается на нужный столбец, т.е.

$ ./col.bash 2
b
e
h
k

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

решение3

Использование Bash и AWK в этом случае будет очень сложным. Я не смог решить проблему предложенными здесь решениями. У вас будет много проблем с "/ '/... поэтому здесь необходим один инструмент.

Используйте так же gawk, как обсуждалось в теме.Инструмент выбора ECG Bash.

# https://codereview.stackexchange.com/a/146370/122105
#!/usr/bin/gawk -f

# https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html
@include "join.awk"

BEGIN {
    FS = "\"*,\"*";
    last_row = 0;
}

BEGINFILE {
    rows[0][ARGIND] = gensub(".*P([0-9]*)C.*", "\\1", "g", FILENAME);
}

{
    rows[FNR][ARGIND] = $col;
    if (FNR > last_row) { last_row = FNR; }
}

END {
    for (r = 0; r <= last_row; r++) {
        print join(rows[r], 1, ARGC - 1, ",");
    }
}

Пожалуйста, прочитайте полный ответ200_success здесьс прекрасными объяснениями.

Связанный контент