我试图使我的 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
我用;来称呼它的用例示例或完整的脚本这里如果您没有在所有两列 CSV 文件中对要选择哪一列 (1/2) 进行硬编码以获取第二列的联接结果,则该方法有效
#!/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
想要的输出
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
- 每列恰好有两列
- 你想要每个文件的第二列
paste
您可以通过 Awk 和(以及 shell 文件通配)的组合最轻松地完成此操作:
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
这里有很好的解释。