bash - 在指定模式之前在文件中插入多行
问题描述
如果内容有新行并且此内容由函数生成,则无法在匹配行之前添加行
另一种看起来不错的替代方法(使用 shell 脚本在指定模式后将多行插入文件)但它只附加“AFTER”。我需要“之前”
然后将xml内容放入add.txt
sed '/4/r add.txt' $FILE
#/bin/sh
FILE=/tmp/sample.txt
form_xml_string()
{
echo "<number value=\"11942\">"
echo " <string-attribute>\"hello\"</string-attribute>"
echo "</number>"
}
create_file()
{
if [ -e $FILE ]
then
echo "Removing file $FILE"
rm $FILE
fi
i=1
while [ $i -le 5 ]
do
echo "$i" >> $FILE
i=$(( i+1 ))
done
}
create_file
cat $FILE
# file sample.txt has numbers 1 to 5 in each line
# Now append the content from form_xml_string to line before 4
# command I tried
CONTENT=`form_xml_string`
echo "CONTENT is $CONTENT"
sed -i "/4/i $CONTENT" $FILE
cat $FILE
预期输出:
1
2
3
<number value="11942">
<string-attribute>"hello"</string-attribute>
</number>
4
5
实际输出(或错误):sed: -e expression #1, char 31: unknown command: `<'
解决方案
您收到该错误是正常的,您的文本语法与您的 sed 命令不兼容,请允许我详细说明:
/
首先,您的文本中有很多s ,并且/
是 s 中的分隔符sed
,这会混淆命令,这就是您收到该错误的原因。所以你应该转义/
你正在使用的文本中的所有内容,将它们替换为\\/
(额外\
的将由 shell 解释)。其次,在 man for 中
sed
,我们可以看到这条小线/i
:
插入文本,每个嵌入的换行符前面都有一个反斜杠
这意味着您还需要\
在每个换行符之前添加一个,在您的示例中,这意味着\\
在每个echo
.
编辑:
感谢Toby Speight的评论,我注意到我完全忘记了更改sed
分隔符的可能性,这可以让你的生活更轻松,因为你不必在文本中的\\
every 之前添加。/
为此,您只需将此行更改sed -i "/4/i $CONTENT" $FILE
为例如 this sed -i "\\_4_i $CONTENT" $FILE
。
引入这些更改后,您的脚本将变为以下内容:
#! /bin/sh
FILE=/tmp/sample.txt
form_xml_string()
{
echo "<number value=\"11942\">\\"
echo " <string-attribute>\"hello\"</string-attribute>\\"
echo "</number>"
}
create_file()
{
if [ -e $FILE ]
then
echo "Removing file $FILE"
rm $FILE
fi
i=1
while [ $i -le 5 ]
do
echo "$i" >> $FILE
i=$(( i+1 ))
done
}
create_file
cat $FILE
# file sample.txt has numbers 1 to 5 in each line
# Now append the content from form_xml_string to line before 4
# command I tried
CONTENT=`form_xml_string`
echo "CONTENT is $CONTENT"
sed -i "\\_4_i $CONTENT" $FILE
cat $FILE
推荐阅读
- java - 类型不可见 - getter 方法
- python - Python使列表中的每个矩阵大小相同
- npm - 在链接到另一个具有更新版本的本地包后从 npm 安装包
- python-3.x - 如何在 discord.py 中授予用户角色而无需管理角色权限
- javascript - 如何使用 Typescript 访问文件处理程序以在 deno 日志模块中运行刷新方法
- typescript - IIFE 自动执行匿名类中不允许使用装饰器
- laravel - 如何使用控制台创建 laravel 7 应用程序?
- file - 我们可以只使用 jax-rs 上传文件而不使用 jersey 或 rest-easy 等任何实现吗
- javascript - 如何使用嵌入响应
- c++ - c++ 自定义迭代器 const 转换正确完成