我有一个文件夹,里面有多个csv文件,并逐渐命名(从00000.csv开始,到通用的#####。csv)。每个csv文件有4列,行数可变,N。
我想做的是编写某种脚本放置在文件夹中,并在执行时逐步读取每个csv文件,并在每个步骤中-对于第i个csv文件-将所有第三列中的N个值以获得值t,随后第四列中的所有N个值以获得值q,然后计算最终值sqrt(t ^ 2 + q ^ 2)并将其打印在(例如txt)文件的第i行,所有csv文件都在同一文件夹内生成。
我想要一种自动化的方法,一种“走而忘了”的方法,而不仅仅是每次更改的命令。
按照@Ed Morton的建议,我将到目前为止可以编写的代码放在这里:
#!/bin/bash
shopt -s nullglob
for f in *.csv
do
cat "$f" | awk -F "," '{sum3 += $3} {sum4 += $4} {final = sqrt(sum3^2 + sum4^2)} END {print final}' > result.txt
done
看起来它以某种方式成功完成了我需要的操作,但是问题在于,由于它不断覆盖前一个csv文件,因此它只显示最后一个csv文件的正确值。
假设我有以下##### = 3个csv文件:
00000.csv
1.817675, 0.859327, 0.959465, 0.281827
4.264659, 3.040230, -0.787732, -0.616018
3.645565, 2.943500, -0.424509, -0.905424
0.603874, 3.858309, -0.302506, -0.953147
0.056403, 0.410131, 0.941520, 0.336956
00001.csv
1.762620, 0.775846, -0.550544, -0.834806
4.364223, 3.049563, 0.995636, 0.093324
3.675804, 2.848182, 0.302385, -0.953186
0.696330, 3.820203, 0.924550, -0.381060
0.154763, 0.428169, 0.983598, 0.180376
00002.csv
1.781079, 0.677564, 0.184586, -0.982816
4.264546, 3.057596, -0.996768, 0.080330
3.718724, 2.757861, 0.429205, -0.903207
0.733074, 3.913208, 0.367446, 0.930045
0.088634, 0.353155, -0.661285, -0.750135
我最后想要得到的是以下result.txt文件:
result.txt
1.895572658137904
3.262622157794096
1.761036700624096
例如在哪里
1.895572658137904 = sqrt [(0.959465-0.787732-0.424509-0.302506 + 0.941520)^ 2 + (0.281827-0.616018-0.905424-0.953147 + 0.336956)^ 2]
以此类推,以获取其他值。
答案 0 :(得分:2)
将GNU awk用于ENDFILE,并通过提供的示例输入/输出进行测试:
awk -F ',' '
{ sum3 += $3; sum4 += $4 }
ENDFILE { printf "%.15f\n", sqrt(sum3^2 + sum4^2); sum3=sum4=0 }
' *.csv
1.895572658137904
3.262622157794095
1.761036700624095
以及任何awk:
awk -F ',' '
{ sum3[FILENAME] += $3; sum4[FILENAME] += $4 }
END {
for (i=1; i < ARGC; i++) {
fname = ARGV[i]
printf "%.15f\n", sqrt(sum3[fname]^2 + sum4[fname]^2)
}
}
' *.csv
1.895572658137904
3.262622157794095
1.761036700624095
答案 1 :(得分:0)
好的,我不是最擅长的,但是我认为这可能有用(我也不了解最后一部分,所以我只把最后一个数字扔到了txt文件中)
for file in [here you put the path of the directory with csv files]/*.csv; do
t=0
q=0
for row in $file;do
tt=`echo "$row"|awk -F, '{print $3}'`
tq=`echo "$row"|awk -F, '{print $4}'`
t=`echo $((t + tt))`
q=`echo $((q + tq))`
done
t=`echo $((t ** 2))`
q=`echo $((q ** 2))`
##finalv is the variable for the final value
finalv=`echo $((t + q))`
echo "$finalv" >> [here you put the path of the directory with csv files]/file.txt
done