Bash while循环+切慢
Bash while loop + cut slow
我正在尝试使用 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/秒。我需要一些东西 运行 快很多。
还有,这里的瓶颈是什么?
瓶颈可能是您为每一行数据生成了多个进程。至于替换,这个awk应该是等价的:
awk '{ split([=10=], a, "\""); print , , a[20] }' TEST.log > IDS.log
Perl 通常非常快:
perl -nE 'say join " ", (split " ")[1,2], (split /"/)[19]' TEST.log > IDS.log
Perl 数组的索引从 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
,第三个放入 ss3
,该行的剩余部分变为 _
。 <&3
导致此行从文件描述符 3. 读取
IFS='"' read -r -a quote_separated_fields
将 "
个字符的标准输入 (FD 0) 上的输入拆分为一个名为 quote_separated_fields
. 的数组
我正在尝试使用 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/秒。我需要一些东西 运行 快很多。
还有,这里的瓶颈是什么?
瓶颈可能是您为每一行数据生成了多个进程。至于替换,这个awk应该是等价的:
awk '{ split([=10=], a, "\""); print , , a[20] }' TEST.log > IDS.log
Perl 通常非常快:
perl -nE 'say join " ", (split " ")[1,2], (split /"/)[19]' TEST.log > IDS.log
Perl 数组的索引从 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
,第三个放入ss3
,该行的剩余部分变为_
。<&3
导致此行从文件描述符 3. 读取
IFS='"' read -r -a quote_separated_fields
将"
个字符的标准输入 (FD 0) 上的输入拆分为一个名为quote_separated_fields
. 的数组