当前位置:  开发笔记 > 编程语言 > 正文

Shell one liner要预先添加到文件中

如何解决《Shelloneliner要预先添加到文件中》经验,为你挑选了12个好方法。

这可能是一个复杂的解决方案.

我正在寻找像">>"这样的简单运算符,但是需要预先添加.

我担心它不存在.我必须做点什么

 mv myfile tmp
 cat myheader tmp > myfile

还有什么更聪明的吗?



1> Jason Navarr..:

这仍然使用临时文件,但至少它在一行:

echo "text" | cat - yourfile > /tmp/out && mv /tmp/out yourfile

Credit:BASH:将文本/行添加到文件中


这意味着猫正在从管道中读取.
在`cat`之后做什么`-`?
警告:如果`yourfile`是一个符号链接,这将无法执行您想要的操作.

2> 小智..:
echo '0a
your text here
.
w' | ed some_file

ed是标准编辑器!http://www.gnu.org/fun/jokes/ed.msg.html


或者,而不是硬编码要插入的文本:`0r header.file`

3> John Mee..:

下面的黑客是一个快速的袖手旁观的答案,工作和收到很多赞成票.然后,随着问题变得越来越流行,时间越来越长,愤怒的人们开始报告它有点工作,但奇怪的事情可能会发生,或者根本就没有用,所以它被激怒了一段时间.好好玩.

该解决方案利用了系统上文件描述符的精确实现,并且由于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


请谨慎使用!请参阅以下注释:http://stackoverflow.com/questions/54365/prepend-to-a-file-one-liner-shell/2754039#2754039
警告:检查输出以确保没有任何更改,但第一行.我使用了这个解决方案,虽然它似乎有用,但我注意到似乎添加了一些新的线条.我不明白它们来自哪里,所以我不能确定这个解决方案真的有问题,但要注意.
如果它现在不可靠,那么如何用更好的解决方案更新答案呢?

4> 小智..:

John Mee:你的方法不能保证工作,并且如果你预先添加超过4096字节的东西可能会失败(至少gnu awk会发生这种情况,但我认为其他实现会有类似的约束).在这种情况下,它不仅会失败,而且会进入无限循环,它会读取自己的输出,从而使文件增长直到所有可用空间都被填满.

亲自尝试一下:

exec 3<>myfile && awk 'BEGIN{for(i=1;i<=1100;i++)print i}{print}' myfile >&3

(警告:一段时间后杀掉它或者它会填满文件系统)

此外,以这种方式编辑文件是非常危险的,这是非常糟糕的建议,就好像在编辑文件时发生了某些事情(崩溃,磁盘已满),你几乎可以保证文件处于不一致的状态.


@Ikraav:也许吧,但是"评论"很长很精致(也很有用),看起来不太好,也许不适合StackOverflow的有限评论能力.
这应该是一个评论,而不是一个单独的答案.

5> Vinko Vrsalo..:

没有临时文件是不可能的,但这里有一个oneliner

{ echo foo; cat oldfile; } > newfile && mv newfile oldfile

您可以使用其他工具(如ed或perl)来执行此操作而无需临时文件.



6> ehdr..:

值得注意的是,使用像mktemp这样的实用程序安全地生成临时文件通常是个好主意,至少如果脚本将以root权限执行.例如,您可以执行以下操作(再次使用bash):

(tmpfile=`mktemp` && { echo "prepended text" | cat - yourfile > $tmpfile && mv $tmpfile yourfile; } )



7> 小智..:

如果您在您控制的计算机上需要它,请安装包"moreutils"并使用"sponge".然后你可以这样做:

cat header myfile | sponge myfile



8> Eric Woodruf..:

使用bash heredoc可以避免使用tmp文件:

cat <<-EOF > myfile
  $(echo this is prepended)
  $(cat myfile)
EOF

这是因为在执行重定向的cat之前,在评估bash脚本时评估$(cat myfile).



9> dbr..:

当你开始尝试在shell脚本中做一些困难的事情时,我强烈建议用"适当的"脚本语言(Python/Perl/Ruby/etc)重写脚本.

至于在文件前面添加一行,就不可能通过管道来实现,就像你做任何事情一样cat blah.txt | grep something > blah.txt,它无意中使文件空白.有一个叫做sponge可以安装的小实用程序命令(你这样做cat blah.txt | grep something | sponge blah.txt,它会缓冲文件的内容,然后将其写入文件).它类似于临时文件,但您不必明确地执行此操作.但我会说比Perl更糟糕的要求.

可能有一种方法可以通过awk或类似方法来实现,但是如果你必须使用shell脚本,我认为临时文件是迄今为止最容易(/唯一?)的方式.



10> cb0..:

假设您要编辑的文件是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'.


`男人bash | 少'+ /过程替代'

11> Daniel Velko..:

编辑:这打破了.当使用cat和tee预先添加到文件时,请参阅奇怪的行为

覆盖问题的解决方法是使用tee:

cat header main | tee main > /dev/null


如果您发布的解决方案已损坏(并且实际上填满了用户的硬盘驱动器),请向社区寻求帮助并删除您的答案.

12> Max Tsepkov..:

就像Daniel Velkov建议的那样,使用tee.
对我来说,这是一个简单的智能解决方案:

{ echo foo; cat bar; } | tee bar > /dev/null

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有