我有这个sed&find命令
find /home/www/ -name footer.php -exec sed -i 's/<\/body>/testmoe\n<\/body>/'
我需要用file.txt中的数据replacetestmoe,所以它的gona是,
find /home/www/ -name footer.php -exec sed -i 's/<\/body>/file.txt\n<\/body>/'
任何build议来纠正我的命令
为了改善@ Iain的答案,我认为你可以通过一次这样的传递:
#!/bin/sh sed -i '/<\/body/ { r /path/to/file a </body> d }' $1
这将search</body>
,将文件插入缓冲区,将</body>
附加到缓冲区,然后删除原始的</body>
,正如Iain正确指出的那样,不能移动它。
在sed
,必须进行多次传递,因为/RE/r <filename>
命令在/ RE /后面将<filename>
的内容插入到输出中。 使用sed最简单的方法是
这是最容易实现的脚本,你可以从查找调用
#!/bin/bash sed -i '/<\/body>/i xyzzy' $1 sed -i '/xyzzy/r /path/to/file.txt' $1 sed -i '/xyzzy/d' $1
然后
find /home/www -name footer.php -exec /path/to/script {} \;
我知道这有点像老西方国家的玩笑(“你知道怎么去找约维尔吗?”“如果我想去约维尔,我不会从这里出发,先生。”)但是我不会用SED。
尝试
perl -ne '$temp = $_ ; if ( $_ =~ /<\/body>/ ) { open FD2, "file.txt" ; while (<FD2>) { print $_ ; } } ; print $temp;' < foo > bar
perl单线程可能会有点晦涩难懂,所以下面是发生了什么事情的细节。 perl脚本:
perl -n
逐行循环通过STDIN; 对于每一行-e
用单引号调用脚本,其中: $temp = $_
将行存储在临时缓冲区中 if ( $_ =~ /<\/body>/ )
查找包含</body>
open FD2, "file.txt" ; while (<FD2>) { print $_ ; }
open FD2, "file.txt" ; while (<FD2>) { print $_ ; }
:当find</body>
,打开一个文件描述符到file.txt,在一个子循环中读取该文件中的每一行并将其写入STDOUT; 在这个循环中重新使用$_
就是为什么我们不得不在第二步中暂时存储它 print $temp;
无论在步骤3中是否find匹配,都将原来读取的行写入STDOUT 实际的结果是STDIN的每一行都被写入到STDOUT中,但是如果任何一行恰好包含</body>
,则在写出该行之前插入file.txt
的全部内容。
那是你想要的吗? 如果是这样的话,将它封装到find
,redirectSTDIN和STDOUT,并在STDIN上重命名STDOUT后执行,作为练习留给你。 你也应该注意到,如果你的文件中碰巧有不止一个</body>
,你会在每次出现时插入file.txt
的内容。