I am new to shell script and don't know much. I have a set of files on which I want to append some text. I am not sure of a better way to do it, but I am using sed to do so. I have written the following script in bash to do so(I am testing it out with one file out of the set of files in the following). Here, I am replacing </notepads>
with </notepads> "\n" <text to be appended>
in order to append <text to be appended>
after the string </notepads>
in the file UIL_extract.ktr. (</notepads>
occurs only once in the file)
我是shell脚本的新手,不太了解。我有一组文件,我想在其中添加一些文本。我不确定一个更好的方法,但我使用sed这样做。我在bash中编写了以下脚本来执行此操作(我正在使用以下文件集中的一个文件对其进行测试)。在这里,我将 替换为 “\ n” <要附加的文本> ,以便在文件UIL_extract.ktr中的字符串 之后追加 <要附加的文本> 。 ( 在文件中只出现一次)
FILE=UIL_extract.ktr
FIND="</notepads>"
SUB="$FIND"$'\n'`cat add.txt`
echo "Finding $FIND in $FILE"
echo "with $SUB"
sed "s,${FIND},${SUB},g" $FILE > Temp.ktr
This is the error I get when I execute it -
这是我执行时遇到的错误 -
sed: -e expression #1, char 25: unterminated `s' command
Something is not right and I don't know what.
有些东西不对,我不知道是什么。
Thanks in advance.
提前致谢。
PS - I have tried various other things. Eg. if I do -
PS - 我尝试了其他各种各样的东西。例如。如果我做 -
sed 's,"${FIND}","${SUB}",g' $FILE > Temp.ktr
It probably doesn't expand the variables as it does not replace it on the output.
它可能不会扩展变量,因为它不会在输出中替换它。
4 个解决方案
#1
1
You need to get the quoting right - so that bash can read the bash variables.
您需要正确引用 - 以便bash可以读取bash变量。
sed 's,'"${FIND}"','"${SUB}"',g' $FILE > Temp.ktr
The other problem is handling the '/n' in and possibly other characters. I would try something like:
另一个问题是处理'/ n'和可能的其他字符。我会尝试类似的东西:
awk '{print} /<\/notepads>/ {exit}' $FILE > /tmp/f1
awk 'BEGIN{found=0} /<\/notepads>/ {found=1;next} {if (found)print}' $FILE >/tmp/f2
cat /tmp/f1 add.txt /tmp/f2 > Temp.ktr
rm /tmp/f[23]
#2
0
Change your code to SUB="$FIND"$'\n'`cat add.txt` on line #4 and it will work.
在第4行将代码更改为SUB =“$ FIND”$'\ n'`cat add.txt`,它将起作用。
#3
0
You want to add the contents of file add.txt
after you find the text </notepads>
? That's just:
您想在找到文本 后添加文件add.txt的内容?那只是:
awk 'NR==FNR{add = add $0 ORS; next} {print} /<\/notepads>/{printf "%s",add}' add.txt UIL_extract.ktr
sed actually has a r
command specifically for this, but using sed for anything multi-line is not extensible and gets very complicated very fast so you should just learn awk.
sed实际上有一个专门用于此的r命令,但是使用sed进行任何多行都不是可扩展的并且非常快速地变得非常复杂,所以你应该学习awk。
#4
0
To recap:
回顾一下:
The only problem in the original code is that in an s
function's replacement text literal \n
chars. must be \
-escaped - otherwise the sed
command will break.
原始代码中唯一的问题是在s函数的替换文本文字\ n字符中。必须是\ -escaped - 否则sed命令将会中断。
While you could use bash's variable expansion features to escape the newlines in $SUB
- SUB=${SUB//$'\n'/\\$'\n'}
- a much simpler solution is to use sed
's r <file>
function (as @Ed Morton states in his answer), which can be used to output a file's content whenever the preceding context address (regex) matches (after outputting the current line):
虽然您可以使用bash的变量扩展功能来转义$ SUB中的换行符 - SUB = $ {SUB // $''\ n'/ \\ $'\ n'} - 一个更简单的解决方案是使用sed的r
FIND='</notepads>'
sed "\,${FIND}, r add.txt" "$FILE" > Temp.ktr
Note that in order to use ,
as the regex delimiter, the initial delimiter must be \
-escaped.
请注意,为了使用,作为正则表达式分隔符,初始分隔符必须是\ -escaped。
#1
1
You need to get the quoting right - so that bash can read the bash variables.
您需要正确引用 - 以便bash可以读取bash变量。
sed 's,'"${FIND}"','"${SUB}"',g' $FILE > Temp.ktr
The other problem is handling the '/n' in and possibly other characters. I would try something like:
另一个问题是处理'/ n'和可能的其他字符。我会尝试类似的东西:
awk '{print} /<\/notepads>/ {exit}' $FILE > /tmp/f1
awk 'BEGIN{found=0} /<\/notepads>/ {found=1;next} {if (found)print}' $FILE >/tmp/f2
cat /tmp/f1 add.txt /tmp/f2 > Temp.ktr
rm /tmp/f[23]
#2
0
Change your code to SUB="$FIND"$'\n'`cat add.txt` on line #4 and it will work.
在第4行将代码更改为SUB =“$ FIND”$'\ n'`cat add.txt`,它将起作用。
#3
0
You want to add the contents of file add.txt
after you find the text </notepads>
? That's just:
您想在找到文本 后添加文件add.txt的内容?那只是:
awk 'NR==FNR{add = add $0 ORS; next} {print} /<\/notepads>/{printf "%s",add}' add.txt UIL_extract.ktr
sed actually has a r
command specifically for this, but using sed for anything multi-line is not extensible and gets very complicated very fast so you should just learn awk.
sed实际上有一个专门用于此的r命令,但是使用sed进行任何多行都不是可扩展的并且非常快速地变得非常复杂,所以你应该学习awk。
#4
0
To recap:
回顾一下:
The only problem in the original code is that in an s
function's replacement text literal \n
chars. must be \
-escaped - otherwise the sed
command will break.
原始代码中唯一的问题是在s函数的替换文本文字\ n字符中。必须是\ -escaped - 否则sed命令将会中断。
While you could use bash's variable expansion features to escape the newlines in $SUB
- SUB=${SUB//$'\n'/\\$'\n'}
- a much simpler solution is to use sed
's r <file>
function (as @Ed Morton states in his answer), which can be used to output a file's content whenever the preceding context address (regex) matches (after outputting the current line):
虽然您可以使用bash的变量扩展功能来转义$ SUB中的换行符 - SUB = $ {SUB // $''\ n'/ \\ $'\ n'} - 一个更简单的解决方案是使用sed的r
FIND='</notepads>'
sed "\,${FIND}, r add.txt" "$FILE" > Temp.ktr
Note that in order to use ,
as the regex delimiter, the initial delimiter must be \
-escaped.
请注意,为了使用,作为正则表达式分隔符,初始分隔符必须是\ -escaped。