首页 > 解决方案 > 在指定模式之前在文件中插入多行

问题描述

如果内容有新行并且此内容由函数生成,则无法在匹配行之前添加行

另一种看起来不错的替代方法(使用 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: `<'

标签: bashshellsed

解决方案


您收到该错误是正常的,您的文本语法与您的 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

推荐阅读