我有一个巨大的模拟日志文件(大约 6GB)。在该文件的数百万行中,有两行在给定时间内经常重复:
...
Max value of omega = 3.0355
Time = 0.000001
....
Max value of omega = 4.3644
Time = 0.000013
...
Max value of omega = 3.7319
Time = 0.000025
...
...
...
Max value of omega = 7.0695
Time = 1.32125
...
... etc.
我想提取“欧米茄的最大值”和“时间”并将它们作为列保存在单个文件中:
#time max_omega
0.000001 3.0355
0.000013 4.3644
0.000025 3.7319
...etc.
我按如下方式进行:
# The following takes about 15 seconds
grep -F 'Max value of omega' logfile | cut -d "=" -f 2 > max_omega_file.txt
,“时间”也一样
# This also takes about 15 seconds
# Very important: match exactly 'Time =' because there other lines that contain the word 'Time'
grep -F 'Time =' logfile | cut -d "=" -f 2 > time.txt
然后我需要使用该命令paste
创建一个两列文件:Time.txt 作为第一列,“max_omega_file.txt”作为第二列。
如您所见,上述步骤的时间增加了一倍。我想知道是否有一个解决方案可以在一次传递中实现相同的结果,从而节省一些时间?
答案1
sed -n '/^Max/ { s/^.*=\s*//;h; };
/^Time/{ s/^.*=\s*//;G; s/\n/ /;p; }' infile
匹配运行语法
/.../{ ... }
:
其中的命令{...}
将仅在与其中的正则表达式/模式匹配的行上运行/.../
;s/^.*=\s*//
:
删除截至最后的所有内容=
以及空格\s*
(如果有)。h
:
将结果复制到保留空间G
:
将保留空间附加到带有嵌入换行符的模式空间s/\n/ /
:
用模式空间中的空格替换嵌入的换行符p
:
打印图案空间;您P
也可以在这里使用命令。0.000001 3.0355 0.000013 4.3644 0.000025 3.7319 1.32125 7.0695
提出的类似方法@史蒂夫斯利瓦这是s//<replace>/
在最后一场比赛中进行替换的简写:
sed -n '/^Max.*=\s*/ { s///;h; };
/^Time.*=\s*/{ s///;G; s/\n/ /;p; }' infile
答案2
我不能保证它会更快,但你可以在 awk 中做这样的事情:
awk -F' = ' '$1=="Max value of omega" {omega = $2} $1=="Time" {print omega,$2}' file
答案3
$ awk 'BEGIN{print "#time", "omega"} /^Max value of omega =/{omega=$NF; next} /^Time =/{print $NF, omega}' file
#time omega
0.000001 3.0355
0.000013 4.3644
0.000025 3.7319
1.32125 7.0695
但这可能会更快:
$ grep -E '^(Max value of omega|Time) =' file |
awk 'BEGIN{print "#time", "omega"} NR%2{omega=$NF; next} {print $NF, omega}'
#time omega
0.000001 3.0355
0.000013 4.3644
0.000025 3.7319
1.32125 7.0695
答案4
grep
可以一次性搜索多种模式
-e PATTERNS, --regexp=PATTERNS
使用 PATTERNS 作为模式。 If this option is used multiple times or is combined with the -f (--file) option, search for all patterns given. This option can be used to protect a pattern beginning with “-”.
So
grep -F -e 'Max value of omega = ' -e 'Time = ' logfile
will reduce the size of the search space. Then you can post process with one of the other suggestions.