1

我有一个 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: file=/home/user/logs/current,start_date=20130128,

我想做的是在文件中搜索任何值,并让它从找到结果的每一行返回(剪切版本)结果。
例如,搜索“20130128”应返回:

SetOperator,value1,20130128,

这意味着我需要同时处理 command 和 equals 作为分隔符。

我环顾了 SO(即this)并花了一些 Google-fu,虽然我发现“读取”速度很慢并且没有针对诸如此类的大文件进行优化是普遍接受的;我没有找到很多替代方案。

你会推荐我用什么?
谢谢!

4

2 回答 2

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,既不是文件也不是管道。

试试这个:

awk -v re="$1" 'BEGIN{FS=OFS=","} $0~re{print $7,$9,$15,$16,$19,$22,$23,$24}' "${FILEPATH}/${FILE}"
于 2013-01-29T14:33:23.847 回答
0

我没有要测试的 10GB 文件,但 grep 手册页显示了两个可能有帮助的选项:

--line-buffered
在输出上使用行缓冲。这可能会导致性能损失。

--mmap
如果可能,使用 mmap(2) 系统调用来读取输入,而不是默认的 read(2) 系统调用。在某些情况下, --mmap 会产生更好的性能。但是,如果在运行 grep 时输入文件缩小,或者发生 I/O 错误, --mmap 可能会导致未定义的行为(包括核心转储)。

行缓冲选项会使整个命令运行得更慢,但是你会开始更快地获得结果,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
于 2013-01-29T13:25:09.117 回答