macOS下sed指定行插入字符串
MacOS:10.15.7
工作中需求:python调用shell脚本,脚本中要在文本文件中指定行下 添加 指定字符串。
如果不是想硬用MacOS下sed,用gsed与linux下的sed是几乎一样的。
Linux sed 命令是利用脚本来处理文本文件,示例文件
$ cat server.txt
P.1=pattern/test,1000000,100 # 要匹配的行 行号1
P.1.MergeCountEx=2
P.1.Merge.1=pattern/p1
P.1.Merge.2=pattern/p2
比如想在第一行后依次添加一些字符串,这些字符串存在一个record.txt下:
$ cat log.txt
P.1.Merge.1=pattern/ddd1
P.1.Merge.2=pattern/ddd2
P.1.Merge.3=pattern/ddd3
P.1.Merge.4=pattern/ddd4
P.1.Merge.5=pattern/ddd5
P.1.Merge.6=pattern/ddd6
最终希望server.txt变成:
$ cat server.txt
P.1=pattern/test,1000000,100
P.1.MergeCountEx=6
P.1.Merge.1=pattern/ddd1
P.1.Merge.2=pattern/ddd2
P.1.Merge.3=pattern/ddd3
P.1.Merge.4=pattern/ddd4
P.1.Merge.5=pattern/ddd5
P.1.Merge.6=pattern/ddd6
思路
- 1. 先匹配制定模式行号,通过 sed -n "/模式/=" 文件
begin=$(sed -n "/P.1=pattern/=" server.txt) # begin -> 1
定位行号,MacOS下没问题。
- 2. 清除.Merge的内容 (以防万一,不在原文件上进行修改,放到server.1.txt中)
sed "/P.1.Merge.*/d" server.txt > server.1.txt
清除内容,macOS下没问题。
$ cat server.1.txt
P.1=pattern/test,1000000,100
只剩一行了,接下来先添加每一行,在所有行添加好了以后再添加Count那一行。
先试试随便添加一串字符串
- 3. 在此行号后添加一串字符串 ,如"string",Linux下
sed -i "${begin} a\\string" server.1.txt
能够成功,其中-i表示在原文件下修改,a表示添加行,多加的‘\’为了防止后面的字符串被转义
但是MacOS下报错:
$ sed: 1: "server.1.txt": unterminated substitute in regular expression
“正则表达式中未终止替换“,看到这篇文章提到:要加上 -e 替换原文件,
加入后执行:
sed -i -e "${begin} a\\string" server.1.txt
报错:
sed: 1: "1 a\string": extra characters after \ at the end of a command
“在'\'后的命令末尾额外字符“?
在终端测试了一下,在输入‘\’后系统会认为命令没有结束,光标移动到下一行,要接着输入后面的字符。
改:
sed -i -e "${begin} a\\
string" server.1.txt
没有报错,我们再来看一下server.1.txt中是不是我们想要的结果:
$ cat server.1.txt
P.1=pattern/test,1000000,100
string%
除了有一个'%'外,它好像没有问题,再加一行试试,还在第一行后面加
sed -i -e "${begin} a\\
test" server.1.txt
$ cat server.1.txt
P.1=pattern/test,1000000,100
teststring
可以看到,'%'消失了,但是它没有换行,不是我们预期的,再加个换行试试看?
sed -i -e "${begin} a\\
string" server.1.txt
sed -i -e "${begin} a\\
test\\
" server.1.txt
$ cat server.1.txt
P.1=pattern/test,1000000,100
string
完事,先添加string,再加test,那么我们可以把record倒着插入,也可以每插入一行就将要插入的行数+1,我选择了后者。
- 4. 把record插入进来
index=${begin}
cat record.txt | while read line
sed -i -e "${index} a\\
$line\\
" server.1.txt
let "index+=1"
$ cat server.1.txt
P.1=pattern/test,1000000,100
P.1.Merge.1=pattern/ddd1
P.1.Merge.2=pattern/ddd2
P.1.Merge.3=pattern/ddd3
P.1.Merge.4=pattern/ddd4
P.1.Merge.5=pattern/ddd5
咋少了一行。。。在record最后加一行空行完事。
- 5. 加上最后汇总的那一行
count=$((index-begin))
sed -i -e "${begin} a\\
P.1.MergeCountEx=${count}\\
" server.1.txt
$ cat server.1.txt
P.1=pattern/test,1000000,100
P.1.MergeCountEx=6
P.1.Merge.1=pattern/ddd1
P.1.Merge.2=pattern/ddd2
P.1.Merge.3=pattern/ddd3
P.1.Merge.4=pattern/ddd4
P.1.Merge.5=pattern/ddd5
P.1.Merge.6=pattern/ddd6
打完收工。
整个shell文件
begin=$(sed -n "/P.1=pattern/=" server.txt)
index=$begin
echo ${index}
sed "/P.1.Merge.*/d" server.txt > server.1.txt
cat log.txt | while read line
sed -i -e "${index} a\\
$line\\
" server.1.txt
let "index+=1"
echo $index