我目前使用长管道bash
命令从这样的文本文件中提取数据,其中 $ f 是我的文件:
result=$(grep "entry t $t " $f | cut -d ' ' -f 5,19 | \
sort -nk2 | tail -n 1 | cut -d ' ' -f 1)
我使用的脚本可以对 $ f 进行数百次类似的搜索,根据我提取的内容,以各种方式对所选行进行排序。我喜欢带有一堆管道的单行bash
字符串,因为它紧凑而且容易,但它可能需要永远。有谁能建议更快的替代方案?也许是先将整个文件加载到内存中的东西?
由于
答案 0 :(得分:0)
通过gawk
或awk
执行asorti
整个管道,您可能会得到提升:
contents="$(cat "$f")"
result="$(awk -vpattern="entry t $t" '$0 ~ pattern {matches[$5]=$19} END {asorti(matches,inds); print inds[1]}' <<<"$contents")"
这将读取&#34; $ f&#34;在变量中,我们将使用单个awk
命令(好吧,gawk
)来完成所有其余的工作。以下是它的工作原理:
awk
的{{1}}变量,其中包含shell变量pattern
< / LI>
t
的条目进行排序,使matches
是一个数组,其中包含inds
中的键的顺序按排序顺序排列的值matches
处理shell变量awk
中的值,就好像它是一个文件一样正在阅读然后你可以只为每个模式更新模式,而不必每次都从磁盘读取文件,并且不需要为所有管道提供如此多的额外进程。
你必须进行基准测试才能确定它是否真的更快或更好,如果表现很重要,你真的应该考虑转移到正确的&#34;语言而不是shell脚本。
答案 1 :(得分:0)
由于您还没有提供示例输入/输出,这只是一个猜测,我只发布它,因为已经发布了您不应该做的其他答案,所以 - 这可能是你想要的那一行:
result=$(awk -v t="$t" '
BEGIN { regexp = "entry t " t " " }
$0 ~ regexp {
if ( ($6 > maxKey) || (maxKey == "") ) {
maxKey = $6
maxVal = $5
}
}
END { print maxVal }
' "$f")
我怀疑你的真正的性能问题不是那个脚本,而是你正在运行它,也许还有其他人在你没有向我们展示过的循环中。如果是,请参阅why-is-using-a-shell-loop-to-process-text-considered-bad-practice并发布更好的示例,以便我们为您提供帮助。