我有这个 sed 和 find 命令
find /home/www/ -name footer.php -exec sed -i 's/<\/body>/testmoe\n<\/body>/'
我需要用 file.txt 中的数据替换 testmoe,这样它就会
find /home/www/ -name footer.php -exec sed -i 's/<\/body>/file.txt\n<\/body>/'
任何纠正我的命令的建议
答案1
为了稍微改进@Iain 的答案,我认为您只需像这样一次即可完成:
#!/bin/sh
sed -i '/<\/body/ {
r /path/to/file
a </body>
d
}' $1
这将搜索</body>
,将文件插入缓冲区,附加</body>
到缓冲区,然后删除原始文件</body>
,正如Iain正确指出的那样,该文件无法移动。
答案2
由于命令会将的内容插入到 /RE/ 之后的输出中,因此sed
您必须进行多次传递。使用 sed 执行此操作的最简单方法是/RE/r <filename>
<filename>
- 在第一轮的 /RE/ 前插入“标记文本”
- 将文件内容插入第二遍的“标记文本”之后
- 删除第三遍中的“标记文本”
最容易实现的是使用可以从 find 中调用的脚本
#!/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 {} \;
答案3
我知道这有点像西部乡村的老笑话(“你知道如何去约维尔吗?”“如果我想去约维尔,我就不会从这里出发,先生。”)但我不会使用 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 $_ ; }
:</body>
找到后,打开 file.txt 的文件描述符,并在子循环中读取该文件中的每一行并将其写入 STDOUT;在这个循环中重复使用$_
就是我们必须在步骤 2 中将其临时存储的原因print $temp;
无论步骤 3 中是否找到匹配项,都将最初读取的行写入 STDOUT
实际的结果是 STDIN 的每一行都写入 STDOUT,但如果任何行恰好包含,则在写出该行之前会插入的</body>
全部内容。file.txt
这就是你想要的吗?如果是这样,那么将它包装在 中find
,重定向 STDIN 和 STDOUT,并在执行后将 STDOUT 重命名为 STDIN,就留给你练习了。你还应该注意,如果你的文件中恰好有多个,那么每次出现 时,</body>
你都会得到 的内容。file.txt