这可能是一个复杂的解决方案.
我正在寻找像">>"这样的简单运算符,但是需要预先添加.
我担心它不存在.我必须做点什么
mv myfile tmp cat myheader tmp > myfile
还有什么更聪明的吗?
这仍然使用临时文件,但至少它在一行:
echo "text" | cat - yourfile > /tmp/out && mv /tmp/out yourfile
Credit:BASH:将文本/行添加到文件中
echo '0a your text here . w' | ed some_file
ed是标准编辑器!http://www.gnu.org/fun/jokes/ed.msg.html
下面的黑客是一个快速的袖手旁观的答案,工作和收到很多赞成票.然后,随着问题变得越来越流行,时间越来越长,愤怒的人们开始报告它有点工作,但奇怪的事情可能会发生,或者根本就没有用,所以它被激怒了一段时间.好好玩.
该解决方案利用了系统上文件描述符的精确实现,并且由于nixes之间的实现差别很大,因此它的成功完全取决于系统,绝对是不可移植的,并且不应该依赖于任何甚至非常重要的东西.
现在,尽管如此,答案是:
为文件创建另一个文件描述符(exec 3<> yourfile
)从而写入那个(>&3
)似乎克服了同一文件困境中的读/写.使用awk为600K文件工作.然而,使用'cat'尝试相同的技巧失败了.
将prependage作为变量传递给awk(-v TEXT="$text"
)克服了字面引号问题,该问题阻止了使用'sed'执行此操作.
#!/bin/bash text="Hello world What's up?" exec 3<> yourfile && awk -v TEXT="$text" 'BEGIN {print TEXT}{print}' yourfile >&3
John Mee:你的方法不能保证工作,并且如果你预先添加超过4096字节的东西可能会失败(至少gnu awk会发生这种情况,但我认为其他实现会有类似的约束).在这种情况下,它不仅会失败,而且会进入无限循环,它会读取自己的输出,从而使文件增长直到所有可用空间都被填满.
亲自尝试一下:
exec 3<>myfile && awk 'BEGIN{for(i=1;i<=1100;i++)print i}{print}' myfile >&3
(警告:一段时间后杀掉它或者它会填满文件系统)
此外,以这种方式编辑文件是非常危险的,这是非常糟糕的建议,就好像在编辑文件时发生了某些事情(崩溃,磁盘已满),你几乎可以保证文件处于不一致的状态.
没有临时文件是不可能的,但这里有一个oneliner
{ echo foo; cat oldfile; } > newfile && mv newfile oldfile
您可以使用其他工具(如ed或perl)来执行此操作而无需临时文件.
值得注意的是,使用像mktemp这样的实用程序安全地生成临时文件通常是个好主意,至少如果脚本将以root权限执行.例如,您可以执行以下操作(再次使用bash):
(tmpfile=`mktemp` && { echo "prepended text" | cat - yourfile > $tmpfile && mv $tmpfile yourfile; } )
如果您在您控制的计算机上需要它,请安装包"moreutils"并使用"sponge".然后你可以这样做:
cat header myfile | sponge myfile
使用bash heredoc可以避免使用tmp文件:
cat <<-EOF > myfile $(echo this is prepended) $(cat myfile) EOF
这是因为在执行重定向的cat之前,在评估bash脚本时评估$(cat myfile).
当你开始尝试在shell脚本中做一些困难的事情时,我强烈建议用"适当的"脚本语言(Python/Perl/Ruby/etc)重写脚本.
至于在文件前面添加一行,就不可能通过管道来实现,就像你做任何事情一样cat blah.txt | grep something > blah.txt
,它无意中使文件空白.有一个叫做sponge
可以安装的小实用程序命令(你这样做cat blah.txt | grep something | sponge blah.txt
,它会缓冲文件的内容,然后将其写入文件).它类似于临时文件,但您不必明确地执行此操作.但我会说比Perl更糟糕的要求.
可能有一种方法可以通过awk或类似方法来实现,但是如果你必须使用shell脚本,我认为临时文件是迄今为止最容易(/唯一?)的方式.
假设您要编辑的文件是my.txt
$cat my.txt this is the regular file
您想要添加的文件是标题
$ cat header this is the header
确保头文件中有最后一个空行.
现在你可以用它作为前缀
$cat header <(cat my.txt) > my.txt
你结束了
$ cat my.txt this is the header this is the regular file
据我所知,这只适用于'bash'.
编辑:这打破了.当使用cat和tee预先添加到文件时,请参阅奇怪的行为
覆盖问题的解决方法是使用tee
:
cat header main | tee main > /dev/null
就像Daniel Velkov建议的那样,使用tee.
对我来说,这是一个简单的智能解决方案:
{ echo foo; cat bar; } | tee bar > /dev/null