【问题标题】:Is there a way to update the same file which is getting read for loop?有没有办法更新正在读取循环的同一文件?
【发布时间】:2021-02-15 05:17:56
【问题描述】:

我有一个 while 循环逐行读取文件。基于某些条件,我想删除同一个文件的几行以减少循环时间(因为文件有数百万行)。 有没有可能的方法? 下面是代码示例:

while read -r line
do
<Processing>
sed -i "/<pattern>/d" $file
done < "$file"

当我运行上述代码时,它不会在运行时删除行。我只能在循环结束后才能看到更新的 $file(这不会减少循环时间)。

【问题讨论】:

  • 这甚至可以用任何其他语言实现吗?

标签: bash shell unix optimization time


【解决方案1】:

认为会发生以下情况:

  1. Bash 打开一个指向$file 当前引用的inode 的文件指针。
  2. read 读取到文件指针的第一个换行符。
  3. sed 读取当前由$file 引用的inode,创建一个新文件,该文件具有相同的路径但不同的inode,其中包含原始文件中某些行的副本.
  4. 从 2 开始重复。

基本上,这不会进行就地替换,因为read 一直从一个inode 读取,而sed 不断创建具有相同路径的包含新内容的新inode。

更快的解决方案是构建一个包含所有替换的sed 脚本,并在循环之后运行该一次。脚本看起来像这样:

/foo/d
/bar/d
…

或者这个:

/foo\|bar\|…/d

【讨论】:

  • 我认为你是对的。由于sed 正在执行的操作,它不可能就地替换文件。这需要一个具有固定记录结构的文件。我想知道 OP 想要用这个程序实现什么语义,当他用 sed 更改他即将在循环中处理的同一个文件时......
  • 感谢您调查问题。我知道在运行时更新同一个循环文件​​有点奇怪。我会清除我的意图。我必须处理具有一百万行的文件的每一行。让我们举个例子,在第 1 行有 A B C D。获取第 1 行输入,我们发现不需要处理那些包含 A 的行。我们可以做点什么,甚至不看那些包含 'A' 的行相同的文件,从而节省运行时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多