1

我试图在 xml 文件中的特定行之前插入几行。虽然它正在工作,但格式没有保留。前导空格被忽略。我知道我们必须使用 IFS= 并且除了许多其他链接之外,我还在以下链接中进行了交叉检查,但无济于事。:(

谁能指出我在这里犯的错误?

在读取>>在bash中逐行写入文件时保留前导空格

while read line
do
    pattern=keepDependencies
    input_file=/home/john/data_file
    file_to_change="${backup_dir}/"$line"/config.xml"

    while IFS= read -r insert_text
    do
        sed -i "/$pattern/i $insert_text" $file_to_change
    done < "$input_file"
done < days_to_keep_absent



数据文件:

[john ~]$ cat data_file
  <logRotator>
        <daysToKeep>-1</daysToKeep>
        <numToKeep>5</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
  </logRotator>



配置.xml:

<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description>I&apos;ll clean all the temporary permissions</description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <hudson.security.AuthorizationMatrixProperty>
    ...
    ...



输出:

<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description>I&apos;ll clean all the temporary permissions</description>
<logRotator>
<daysToKeep>-1</daysToKeep>
<numToKeep>5</numToKeep>
<artifactDaysToKeep>-1</artifactDaysToKeep>
<artifactNumToKeep>-1</artifactNumToKeep>
</logRotator>
  <keepDependencies>false</keepDependencies>
  <properties>
    <hudson.security.AuthorizationMatrixProperty>
    ...
    ...
4

2 回答 2

1

不是read哪个给你带来问题。是sed

发出i命令的通常(据我所知,也是唯一与 Posix 兼容的)方式是在它后面立即加上反斜杠和换行符。参数由后续行组成,直到第一行不以反斜杠结尾:

/pattern/i\
    This text is inserted\
So is this text.

GNUsed允许插入的文本在 . 的同一行开始i紧跟在任何空格之后。这就是为什么您的空白被删除的原因。

尝试这个:

while read line
do
  pattern=keepDependencies
  input_file=/home/john/data_file
  # Note: I fixed quoting in the following line.
  file_to_change="$backup_dir/$line/config.xml"

  while IFS= read -r insert_text
  do
    # Note: \\ is reduced to \ because it is inside a double-quoted string
    # The newline is inserted directly. So sed sees i\<newline><inserted text>
    sed -i "/$pattern/i\\
$insert_text" "$file_to_change"
  done < "$input_file"
done < days_to_keep_absent

我发现这种风格有点难以阅读,所以我通常会这样做:

ICMD='i\
'

# ...

sed -i "/$pattern/$ICMD$insert_text" "$file_to_change"
于 2013-12-27T00:28:53.380 回答
0

这是 read 的一个功能(以及许多其他 shell 的功能)。

您可以解决它:只需在文件中添加一个字符(例如:“|”),并在输出该行时将其取出

我会在不检查的情况下重用你的算法(你说它确实做了你需要做的事情,除了缺少前导空格):

while 循环变为:

sed -e 's/^/|/' < "${input_file}" > "${input_file}_modified"
while IFS= read -r insert_text
do
    sed -i "/$pattern/i $( echo "$insert_text" | sed -e 's/^|//' )" $file_to_change
done < "${input_file}_modified"

希望这可以帮助

于 2013-12-26T10:23:39.480 回答