awk性能和CPU运行时间

tom*_*sen 1 awk cut

我有一个包含数百万行和数千列/字段的输入文件.任何人都可以向我解释,为什么下面两个产生相同输出的awk方法在CPU运行时间方面差别很大?

175.0秒:

awk 'BEGIN{FS=":| "}NR>1{field1=$1;field2=$2;$1="";$2="";print field1":"field2,field1":"field2,field2,$0}' file_in > file_out
Run Code Online (Sandbox Code Playgroud)

19.7秒:

cat file_in | awk 'BEGIN{FS=":"}NR>1{print $1,$2}' | awk '{print $1":"$2,$1":"$2,$0}' | cut -d " " -f 3 --complement > file_out
Run Code Online (Sandbox Code Playgroud)

这是一个file_in的第二行和第三行,只有几百个列/字段(行之间没有换行符):

1:1000071 C T 1 0 0 1 0 0
1:1000759 C T 1 0 0 0 1 0
Run Code Online (Sandbox Code Playgroud)

以下是file_out的相应行:

1:1000071 1:1000071 1000071 C T 1 0 0 1 0 0
1:1000759 1:1000759 1000759 C T 1 0 0 0 1 0
Run Code Online (Sandbox Code Playgroud)

Ed *_*ton 6

这两个陈述:

$1="";$2=""
Run Code Online (Sandbox Code Playgroud)

导致awk重新编译每个记录两次.鉴于每个行数百万行和数千个字段,我预计会产生影响.

如果您向我们展示几行代表性样本输入和预期输出,我们可以向您展示如何简洁有效地完成它.

它看起来像你正在做的是转换像这样的行:

1:1000071 C T 1 0 ...
1:1000759 C T 1 0 ...
Run Code Online (Sandbox Code Playgroud)

像这样的行:

1:1000071 1:1000071 1000071 C T 1 0 ...
1:1000759 1:1000759 1000759 C T 1 0 ...
Run Code Online (Sandbox Code Playgroud)

如果是这样,你需要做的就是:

awk '{x=$1; sub(/[^:]+:/,x" "x" ")}1' file
Run Code Online (Sandbox Code Playgroud)

或者因为这是一行上的简单替换,即使是sed也可以处理它:

sed 's/\([^:]*:\)\([^ ]*\)/\1\2 \1\2 \2/' file
Run Code Online (Sandbox Code Playgroud)

看:

$ cat file
1:1000071 C T 1 0 ...
1:1000759 C T 1 0 ...

$ awk '{x=$1; sub(/[^:]+:/,x" "x" ")}1' file
1:1000071 1:1000071 1000071 C T 1 0 ...
1:1000759 1:1000759 1000759 C T 1 0 ...

$ sed 's/\([^:]*:\)\([^ ]*\)/\1\2 \1\2 \2/' file
1:1000071 1:1000071 1000071 C T 1 0 ...
1:1000759 1:1000759 1000759 C T 1 0 ...
Run Code Online (Sandbox Code Playgroud)

啊,但我看到你提到你的样本输入来自第2行,所以我猜你有一个标题行或者要跳过的东西.那是:

awk 'NR>1{x=$1; sub(/[^:]+:/,x" "x" ");print}' file

sed -n '2,$s/\([^:]*:\)\([^ ]*\)/\1\2 \1\2 \2/p' file
Run Code Online (Sandbox Code Playgroud)

最后 - 这是一个替代的awk解决方案,如果您的行都以"1:"开头,可能会更有效,如示例输入中所示:

awk 'NR>1{print $1, $1, substr($0,3)}' file
Run Code Online (Sandbox Code Playgroud)