我正在尝试使用bash循环处理文件(1.5GB)来迭代每一行。我使用cut
来简化(相对),最后得到:
while read line
do
echo "$(echo $line | cut -d' ' -f 2-3)" "$(echo $line | cut -d'"' -f 20)"
done < TEST.log > IDS.log
这非常慢,只有大约2KB /秒。我需要更快的速度运行。
此外,这里的瓶颈是什么?
答案 0 :(得分:4)
瓶颈可能是您为每行数据生成多个进程。至于替换,这个awk应该是等价的:
awk '{ split($0, a, "\""); print $2, $3, a[20] }' TEST.log > IDS.log
答案 1 :(得分:4)
Perl通常非常快:
perl -nE 'say join " ", (split " ")[1,2], (split /"/)[19]' TEST.log > IDS.log
Perl数组从0开始编制索引。
答案 2 :(得分:0)
这里最大的瓶颈是分解管道的子流程。只需消除命令替换和管道,即可获得显着的性能提升(参见:数量级)。
while IFS=$'\x01' read -r ss1 ss2 ss3 _ <&3 && \
IFS='"' read -r -a quote_separated_fields; do
printf '%s\n' "${ss2} ${ss3} ${quote_separated_fields[20]}"
done < TEST.log 3< <(tr ' ' $'\x01' <TEST.log) > IDS.log
这是如何工作的?
tr ' ' $'\x01'
将输入中的空格更改为低ASCII字符,以避免特殊情况的处理(其中read
会将空白行合并为单个字符)。将其放在3< <(...)
之后将此操作的输出放在文件描述符#3上。IFS=$'\x01' read -r ss1 ss2 ss3 _ <&3
在这些字符上分割一行,将第一个字段放入ss1
(我们不在乎),第二个字段放入ss2
,第三个字段放入{{1 }},并将该行的其余部分插入ss3
。 _
导致此行从文件描述符3读取。<&3
将标准输入(FD 0)上IFS='"' read -r -a quote_separated_fields
个字符的输入拆分为一个名为"
的数组。