我有一个10GB的CSV文件,我正试图从中剪切选择输出。 目前我已经得到了以下内容,但由于它的大小,它消耗(方式)太多资源,所以我希望优化它。
#!/bin/bash
FILE=data.txt
FILEPATH=/home/user/
if [[ -z $1 ]]; then
echo "No search parameter specified. Specify one when running this."
fi
echo "Searching $FILEPATH/$FILE for $1.. this may take a while."
echo ""
while IFS= read -r LINE;
do
# Grep for $1 and cut select columns
grep $1 | cut -d"," -f7,9,15,16,19,22,23,24
done
输入文件的示例行如下所示:
结果:key = value1,error = 0,command = SetOperator | SOURCE: 文件= /家庭/用户/日志/电流,起始日期= 20130128,
我想要做的是搜索文件中的任何值,并从找到结果的每一行返回(剪切版本)结果。
例如,搜索“20130128”应返回:
SetOperator,value1,20130128,
这意味着我需要同时处理命令和equals作为分隔符。
我已经环顾了SO(即this)并花了一些Google-fu,而我发现人们普遍认为“阅读”很慢并且没有针对像这样的大文件进行优化;我没有找到很多替代品。
您建议我使用什么?
谢谢!
答案 0 :(得分:1)
你的命令如下:
while IFS= read -r LINE;
do
# Grep for $1 and cut select columns
grep $1 | cut -d"," -f7,9,15,16,19,22,23,24
done
永远不会终止,因为你没有在任何文件或管道上运行grep。
使用grep加上管道加切割代替那个循环,试试这个:
awk -v re="$1" 'BEGIN{FS=OFS=","} $0~re{print $7,$9,$15,$16,$19,$22,$23,$24}' "${FILEPATH}/${FILE}"
答案 1 :(得分:0)
我没有要测试的10GB文件,但是grep手册页显示了两个可能有用的选项:
- 行缓冲
在输出上使用行缓冲。这可能会导致性能下降。- MMAP
如果可能,使用mmap(2)系统调用来读取输入,而不是默认的read(2)系统调用。在某些情况下, --mmap产生 更好的性能。但是, - mmap可能会导致未定义的行为 (包括核心转储)如果输入文件收缩而grep是 操作,或者发生I / O错误。
行缓冲选项会使整个命令运行得慢,但是你会开始更快地得到结果,mmap可能很奇怪。
使用这些选项然后循环将是不必要的,如下所示:
grep --mmap "pattern" file | cut -d"," -f7,9,15,16,19,22,23,24
或
grep --line-buffered "pattern" file | cut -d"," -f7,9,15,16,19,22,23,24