【发布时间】:2021-11-13 01:45:21
【问题描述】:
我运行一个测试环境,在其中我使用 lorem alg 创建了 40 000 个测试文件。文件大小在 200k 到 5 MB 之间。我想修改很多随机文件。我将通过删除 2 行并使用 base64 字符串插入 1 行来更改 5% 的行。
问题是这个过程需要很多时间每个文件。我尝试通过将 testfile 复制到 ram 并在那里进行更改来修复它,但我看到一个仅使用一个完整核心的单个线程和 gawk 显示最多的 cpu 工作。我正在寻找一些解决方案,但我找不到正确的建议。我认为 gawk 可以一步完成,但是对于大文件,当我使用“getconf ARG_MAX”进行计算时,我会得到一个很长的字符串。
如何加快速度?
zeilen=$(wc -l < testfile$filecount.txt);
durchlauf=$(($zeilen/20))
zeilen=$((zeilen-2))
for (( c=1; c<=durchlauf; c++ ))
do
zeile=$(shuf -i 1-$zeilen -n 1);
zeile2=$((zeile+1))
zeile3=$((zeile2+1))
string=$(base64 /dev/urandom | tr -dc '[[:print:]]' | head -c 230)
if [[ $c -eq 1 ]]
then
gawk -v n1="$zeile" -v n2="$zeile2" -v n3="$zeile3" -v s="$string" 'NR==n1{next;print} \
NR==n2{next; print} NR==n3{print s}1' testfile$filecount.txt > /mnt/RAM/tempfile.tmp
else
gawk -i inplace -v n1="$zeile" -v n2="$zeile2" -v n3="$zeile3" -v s="$string" 'NR==n1{next; print} \
NR==n2{next; print} NR==n3{print s}1' /mnt/RAM/tempfile.tmp
fi
done
【问题讨论】:
-
听起来好像是 CPU 受限,而不是 I/O 受限。也许您可以使用multi-threading 来并行处理文件?
-
gawk 不是你的问题。在 shell 循环中重复调用 gawk 和其他工具是您的问题。有关详细信息,请参阅why-is-using-a-shell-loop-to-process-text-considered-bad-practice。 edit 您的问题显示minimal reproducible example 具有简洁、可测试的样本输入和预期输出,并解释您的要求,以便我们为您提供帮助。您可能还希望在发布示例时使用英文变量名,以便更多人能够理解您的代码。
-
一次性完成确实会快得多,并且可以使用小而恒定大小的参数来完成。
-
{next; print}并没有像您认为的那样做;next说要跳过gawk脚本的其余部分,回到gawk脚本的开头并处理下一个输入 =>print永远不会被处理;这就解释了为什么{next; loop change same fileprint}不会产生错误……loop change same fileprint永远不会被读取/处理;我假设您想跳过当前行,阅读下一行并从脚本中的同一点继续处理,在这种情况下,您可能想用getline替换next,尽管'next' 应该足够了整体逻辑的一些变化 -
to:Ed Morton:我想改变量名,但后来我忘了。
to:mark-fuso:我从其他帖子中复制了它。对于一份小工作来说,很难理解 awk。 “循环更改相同的文件打印”是一个复制错误 - 不是我的。我会删除它
标签: bash performance file awk