在Linux中动态更改文件(通过管道写入输入文件)

在Linux中动态更改文件(通过管道写入输入文件)

如何沿管道动态地更改文件?

我可能正在寻找一种在管道开头缓冲文件的方法,这与此形成对比:

    cat foo.txt | grep bar > foo.txt

... 将保护输入数据不被管道本身破坏。有这样的缓冲区吗?

答案1

我猜 sed 仍然可能会创建临时文件,但是下面的操作可能会实现你想要的效果?(对此使用 strace 可能会显示 sed 是否创建了临时文件)。

sed -i '/bar/!d' foo.txt

感叹号反转匹配,d 代表删除,因此这将删除所有不包含 bar 的行。

答案2

尝试使用海绵更多工具像这样:

sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd

它在写入输出之前收集全部输入。

答案3

使用>>来保存内容。

cat foo.txt | grep bar >> foo.txt

现在将其附加到文件。

据我所知,在 shell 中没有直接的方法将数据添加到文件前面。如果要添加,可能需要在中间使用临时文件。

答案4

最好的办法是记住文件在 unix 中的工作方式——只要有指向该文件的链接(打开文件的目录或进程),该文件就存在。

因此,打开文件,删除该目录条目,然后运行写入具有相同名称但链接到不同 inode 的新目录条目的进程。

最后,这个的优点在于它适用于任何类型的管道操作,而不仅仅是可以执行临时文件缓冲区破解的操作。

{ rm file ; sed -e s/this/that/g > file ; } < file

警告——如果您必须将重写作为原子操作,这可能会导致灾难。unix 不提供锁定文件的干净方法,尤其是在 shell 级别。如果您在运行 NIS 之类的繁忙系统上执行诸如编辑密码文件之类的操作,那么在黑暗时代这是一个问题。任何时候,如果有多个进程正在读取/写入文件,如果您的系统繁忙或重要,请务必小心。

唯一 100% 确定是原子的操作是目录条目操作 - rm / ln / mv(在同一文件系统上)。

所以现在事情变得更长、更丑陋了……

其中的数学部分需要 posix shell 或类似扩展的 bourne shell

c=0
    while
      f=$SECONDS
      test -f file.$c.tmp
    do
      c=$(($c+1))
    done

  grep stuff < file > file.$c.tmp && mv file.$c.tmp file

相关内容