Bash 将文本行添加到变量中的特定行

Bash 将文本行添加到变量中的特定行,bash,shell,sed,Bash,Shell,Sed,我有以下文件,CHANGELOG.rst: some text ========= header ------ * list * list header ------ * list 我需要在文件标题后添加一个条目,以便更新后的文件如下所示: some text ========= new header ---------- * new list header ------ * list * list header ------ * list 我补充说 new header

我有以下文件,
CHANGELOG.rst

some text
=========

header
------

* list
* list

header
------

* list
我需要在文件标题后添加一个条目,以便更新后的文件如下所示:

some text
=========

new header
----------

* new list

header
------

* list
* list

header
------

* list
我补充说

new header
----------

* new list
零件已存在于
$CHANGES
变量中


我知道这可以通过
sed
实现,但我不知道如何解决它。

以下是我使用grep的丑陋的解决方案:

grep -B100000 "=========" CHANGELOG.rst > new.txt
echo >> new.txt
echo "new header" >> new.txt
echo "----------" >> new.txt
echo >> new.txt
echo "\* new list" >> new.txt
echo >> new.txt
grep -A100000 "=========" CHANGELOG.rst >> new.txt

grep-A获取匹配字符串后面的行,grep-B获取匹配字符串后面的行。仅当要拆分文件的匹配字符串只存在一次时,此选项才起作用。

以下是我使用grep的丑陋解决方案:

grep -B100000 "=========" CHANGELOG.rst > new.txt
echo >> new.txt
echo "new header" >> new.txt
echo "----------" >> new.txt
echo >> new.txt
echo "\* new list" >> new.txt
echo >> new.txt
grep -A100000 "=========" CHANGELOG.rst >> new.txt

grep-A获取匹配字符串后面的行,grep-B获取匹配字符串后面的行。仅当要拆分文件的匹配字符串只存在一次时,此选项才有效。

With
sed

sed -i '/PATTERN/a  Line which you want to append' filename
-i
用于就地替代

例如:

sed -i "/=========/a ${CHANGES}" file

some text
=========

new header
----------

* new list

header
------

* list
* list

header
------

* list

使用
sed

sed -i '/PATTERN/a  Line which you want to append' filename
-i
用于就地替代

例如:

sed -i "/=========/a ${CHANGES}" file

some text
=========

new header
----------

* new list

header
------

* list
* list

header
------

* list

我不会使用
sed
将值注入文本文件。我会使用
ed

ed file <<EOF
4i
$yourtext
.
w
EOF

ed file我不会使用
sed
将值注入文本文件。我会使用
ed

ed file <<EOF
4i
$yourtext
.
w
EOF

ed file如果要确保仅在第一次出现时执行此操作,请使用以下命令:

CHANGES="line1\nline2"
sed -i "0,/\(^=\+$\)/s//\1\n${CHANGES}/" filename

如果要确保仅在第一次出现时执行此操作,请使用以下命令:

CHANGES="line1\nline2"
sed -i "0,/\(^=\+$\)/s//\1\n${CHANGES}/" filename
但这种情况会发生在每个标题上

具体(根据要求)

但这种情况会发生在每个标题上

具体(根据要求)


我在答案中找到了解决问题的办法

感谢@mklement0,代码是:

sed -i "4 i\
${CHANGES//$'\n'/\\$'\n'}" ./CHANGELOG.rst

我在答案中找到了解决问题的办法

感谢@mklement0,代码是:

sed -i "4 i\
${CHANGES//$'\n'/\\$'\n'}" ./CHANGELOG.rst


看起来不错。但是,你能再解释一下在
$CHANGES
变量周围使用大括号和单/双引号吗?@AndreiHorak大括号不是必需的,而是可取的。双引号用于sed中的变量扩展。我已经更新了答案。好的。然而,我得到了这个错误:
sed:-e表达式#1,char 147:未知命令:“
。我认为它试图将
$CHANGES
的内容用作某种命令,而不是普通字符串。这是因为在CHANGES变量中有
*
。您可以在运行sed命令之前使用
set-f
禁用全局绑定,完成后使用
set+f
启用全局绑定。它不起作用,它会给我同样的错误。另外,没有明确设置/取消设置的情况下,是否还有其他解决方案?看起来不错。但是,你能再解释一下在
$CHANGES
变量周围使用大括号和单/双引号吗?@AndreiHorak大括号不是必需的,而是可取的。双引号用于sed中的变量扩展。我已经更新了答案。好的。然而,我得到了这个错误:
sed:-e表达式#1,char 147:未知命令:“
。我认为它试图将
$CHANGES
的内容用作某种命令,而不是普通字符串。这是因为在CHANGES变量中有
*
。您可以在运行sed命令之前使用
set-f
禁用全局绑定,完成后使用
set+f
启用全局绑定。它不起作用,它会给我同样的错误。另外,没有明确设置/取消设置的情况下,是否还有另一种解决方案?我不怀疑它不会起作用,但我希望有一种更干净的方法:)我不怀疑它不会起作用,但我希望有一种更干净的方法:)你能解释一下
0、
\1
的作用吗?0表示匹配到第一次出现,即,它不会进行多次替换,并且\1将第一组的内容放在正则表达式的转义()之间的替换部分中。在您的情况下,我们将匹配以一个或多个=。因此,我们将\1替换为匹配的=。更多信息好的,这很有意义,但它给了我以下错误:
sed:-e expression#1,char 156:unterminated's'命令
。您使用的是什么版本的sed?这适用于GNU-sed版本4.2.1。这是一样的,
GNU-sed版本4.2.1
。您能解释一下
0、
\1
做什么吗?0表示匹配到第一次出现,即它不会进行多次替换,并且\1将正则表达式转义()之间的第一组内容放入替换部分。在您的情况下,我们将匹配以一个或多个=。因此,我们将\1替换为匹配的=。更多信息好的,这很有意义,但它给了我以下错误:
sed:-e expression#1,char 156:unterminated's'命令
。您使用的是什么版本的sed?这适用于GNU-sed版本4.2.1。这是一样的,
GNU-sed版本4.2.1
。我需要
sed
,用于我的特定情况,而不是一般情况。如果您能修改您的示例以适合我的问题,我们将不胜感激:)我已经有了需要插入变量中的内容。还有,你说的是什么标题?请参阅你另一篇文章中的回复()我需要
sed
来说明我的具体情况,而不是一般情况。如果您能修改您的示例以适合我的问题,我们将不胜感激:)我已经有了需要插入变量中的内容。还有,你在说什么标题?请参阅你另一篇文章中的回复()