如何在循环中使用$的索引前部?

0 bash awk

我正在努力一个简单的循环。我想得到:

awk '{print $3}' z.csv > col1.csv
awk '{print $4}' z.csv > col2.csv
...
awk '{print $(i+2)}' z.csv> col(i).csv
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止尝试过的:

k=$i+2;
for i in {1..21}
do 
 awk '{print $k}' z.csv > col"${i}".csv
done 
Run Code Online (Sandbox Code Playgroud)

但这还行不通,请问任何建议吗?

Ed *_*ton 5

不需要bash循环多次调用awk,只需在1次调用awk之内循环,例如使用GNU awk自动为您处理潜在的“打开文件过多”问题:

awk '{
    for (i=1; i<=21; i++) {
        print $(i+2) > ("col"i".csv")
    }
}' z.csv
Run Code Online (Sandbox Code Playgroud)

以及任何awk:

awk '{
    for (i=1; i<=21; i++) {
        close(out)
        out = "col"i".csv"
        print $(i+2) >> out
    }
}' z.csv
Run Code Online (Sandbox Code Playgroud)

如果在每次迭代中关闭所有文件都导致性能问题,并且您发现可以一次打开11个输出文件而不会出现“打开文件过多”错误,则可以执行以下操作:

awk '{
    for (i=1; i<=21; i++) {
        if (i>11) close(out)
        out = "col"i".csv"
        print $(i+2) >> out
    }
}' z.csv
Run Code Online (Sandbox Code Playgroud)

或稍微更有效,但代码更多:

awk '{
    for (i=1; i<=10; i++) {
        print $(i+2) > ("col"i".csv")
    }
    for (; i<=21; i++) {
        close(out)
        out = "col"i".csv"
        print $(i+2) >> out
    }
}' z.csv
Run Code Online (Sandbox Code Playgroud)