【发布时间】:2016-10-13 19:57:22
【问题描述】:
我需要从一个文件中读取数据并插入到多个文件中(每个文件的大小小于 3mb,文件大小可以不同)。重要的是 - 代理的记录不应该被拆分到多个文件中。我在 UNIX bash 脚本的 While 循环中执行所有这些操作。
Input.csv
Src,AgentNum,PhoneNum
DWH,Agent_1234,phone1
NULL,NULL,phone2
NULL,NULL,phone3
DWH,Agent_5678,phone1
NULL,NULL,phone2
NULL,NULL,phone3
DWH,Agent_9999,phone1
NULL,NULL,phone2
NULL,NULL,phone3
Desired Output -
Output1.csv (less than 3MB)
Src,AgentNum,PhoneNum
DWH,Agent_1234,phone1
NULL,NULL,phone2
NULL,NULL,phone3
Output2.csv (less than 3MB)
Src,AgentNum,PhoneNum
DWH,Agent_5678,phone1
NULL,NULL,phone2
NULL,NULL,phone3
DWH,Agent_9999,phone1
NULL,NULL,phone2
NULL,NULL,phone3
Bash Shell 脚本
#!/bin/bash
BaseFileName=$(basename $FileName | cut -d. -f1)
Header=`head -1 $FileName`
MaxFileSize=$(( 3 * 1024 * 1024 ))
sed 1d $FileName |
while read -r line
do
echo $line >> ${BaseFileName}_${FileSeq}.csv
MatchCount=`echo $line | grep -c -E '^.DWH'`
if [[ $MatchCount -eq 1 ]]
then
FileSizeBytes=`du -b ${BaseFileName}_${FileSeq}.csv | cut -f1`
if [[ $FileSizeBytes -gt $MaxFileSize ]]
then
#Add a header record to each file
sed -i "1i ${Header}" ${BaseFileName}_${FileSeq}.csv
FileSeq=$((FileSeq + 1))
fi
fi
done
它几乎可以正常工作,除了 1)它没有按预期拆分记录(代理的一些记录被拆分到多个文件中) 2)它只为第一个输出文件插入标题记录。 3)太慢了,一个10MB的文件需要3分钟。实际上我有一个 3GB 的文件。
有人可以建议我在哪里做错了。 有没有更好的方法来处理这个问题?
【问题讨论】:
-
很多更好的方法来处理它,是的。在这里使用
du效率非常低,因为您可以只在内部维护一个字节计数器。 -
而
echo $line只是普通的越野车。见BashPitfalls#14 -
另外,修复shellcheck.net 发现的错误 - 通常,作为在此处提问之前的练习。
-
(并且将
>>放在echos 上是低效的——这意味着您每次想要写一行时都重新打开输出文件)。 -
顺便说一句——要清楚,每行前面的标签是文字吗? (如果没有,为什么在正则表达式中
DWH前面有一个通配符?)