我试图在xml文件中的特定行之前插入几行。虽然它可以工作,但格式不会保留。领先的空白被忽略了。我知道我们必须使用IFS =并且除了许多其他链接之外我还在以下链接中进行了交叉检查,但无济于事。 :(
任何人都可以指出我在这里犯的错误吗?
Preserving leading white space while reading>>writing a file line by line in 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>
config.xml中:
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description>I'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'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>
...
...
答案 0 :(得分:1)
这不是read
给你带来问题的。它是sed
。
通常(以及据我所知,唯一与Posix兼容的)发出i
命令的方法是立即使用反斜杠和换行符跟随它。该参数由后续行组成,直到第一行不以反斜杠结尾:
/pattern/i\
This text is inserted\
So is this text.
GNU sed
允许插入的文本与任何空格之后的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"
答案 1 :(得分: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"
希望这有帮助