我经常对文件进行简单的操作,例如:
cat file1.txt|sed -r 's/^ *//'
删除行开头的空格。如果我想覆盖该文件,我知道的唯一方法是:
cat file1.txt|sed -r 's/^ *//' > file2.txt
mv file2.txt file1.txt
这非常烦人,因为我必须检查 file2.txt 是否存在,因为我必须编写两个命令而不是一个,等等。
所以我想:有没有办法在管道命令链中进行完整的文件缓冲?所以我可以写:
cat file1.txt| magicbuffercommand |sed -r 's/^ *//' > file1.txt
该命令应该缓冲(当然,直到最大字节)并等待 EOF,然后应该开始写入 stdout。
有什么东西可以做到这样的事情吗?
答案1
你不需要cat
。sed
愉快地接受文件名作为参数:
sed 's/^ *//' <file>
如果您使用 GNU sed,您可以使用-i
或--in-place
开关就地编辑文件:
sed -i 's/^ *//' <file>
sponge
要回答这个问题,您可以使用以下工具实现“完整文件缓冲”
更多实用程序包。使用
sponge
你可以做:
<command> <file> | sponge <file> # or
<command1> < <file> | <command2> | sponge <file>
使用您的sed
示例,这将变为:
sed 's/^ *//' <file> | sponge <file>
答案2
你看过Linux缓冲区命令吗?这利用用户共享内存段基本上允许并发读/写。我想如果共享内存段足够大,它可以缓冲整个文件。
buffer 命令可能不会自动安装,但我在不同 Linux 发行版的许多存储库中找到了该程序。最糟糕的是,您可以通过谷歌搜索并找到源代码并自己编译/链接它。
我使用缓冲区来加快对磁带驱动器等较慢设备的写入速度,它确实减少了大约 10-20% 的传输时间。
答案3
另一种可能性是将文件的全部内容放入 shell 变量中。曾经有尺寸限制,但我知道这不再是问题。只要你有内存(当然超过物理内存会导致交换),你可以尝试以下操作:
例如:
varx=`cat filename`
echo "$varx" | sed ..... >$filename
我仅在您可能想要使用 sed 命令以外的其他命令时才提及这一点。
答案4
cat 命令没用。直接使用 sed 打印内容或用于-i
进行就地编辑。