
Я пытаюсь сделать свой скрипт 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
здесьс прекрасными объяснениями.