我有一个包含130,000行的.csv
文件。我想读取此文件中的所有行并检查列数是否小于17,然后在行尾添加|0
。
首先我计算了列数,但只有这样,运行时间从10秒增加到近3分钟。
这是我尝试过的:
while read line;
do
nr_columns=$(echo $line | awk -F'|' '{print NF}')
echo $line>> out
done<input_file.csv
我也尝试使用tr
,但运行时间也有所增加。
我怎样才能更快地完成这项工作?
谢谢大家。这就是我所做的:
awk -v separator=$sep -v nr_fields=$header_col -F '$sep' '{ if (NF < nr_fields) print $0separator0;else print $0}' input_file.csv > outputfile
答案 0 :(得分:2)
通过识别awk
不仅仅适用于单行,您可以更快地完成它 - 它是一种真正的编程语言。将其放在文件foo.awk
:
BEGIN {
OFS="|"
}
NF < 17 {
print $0,"0"
}
NF >= 17 {
print
}
然后像awk -F'|' -f foo.awk input_file.csv
一样运行。
答案 1 :(得分:1)
听起来你只需要:
awk -F'|' '{print $0 (NF<17 ? FS 0 : "")}' input_file.csv
但如果没有简洁,可测试的样本输入和预期输出,那只是猜测。
答案 2 :(得分:0)
不确定这是否是您要找的,但这绝对有效。
#!/bin/bash
if [ ! $(head -1 input_file.csv | awk -F'|' '{print NF}') -eq 17 ]; then
echo "input_file.csv does not have 17 columns"
exit 2
fi
sed 's/$/\|0/g' input_file.csv > out
首先,我们检查列数是否确实为17.如果不是,我们发送消息并退出。如果我们处于良好状态,我们会继续将|0
添加到行中。
答案 3 :(得分:0)
除非你真的说“如果一个记录少于17个字段,我知道它有16个字段”,那么我会添加许多新字段到17:
awk 'BEGIN {FS=OFS="|"} NF < 17 {for (i=NF+1; i<=17; i++) $i=0} 1' <<END
1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17
1|2|3|4|5|6|7|8|9|10|11|12|13|14
a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q
END
1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17
1|2|3|4|5|6|7|8|9|10|11|12|13|14|0|0|0
a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q
你的方法如此缓慢的一些原因:
read
命令非常慢:它一次读取一个字节awk