关于sed我常用的几个方法以及遇到坑的整理

shell、grep、sed 和 awk 是 Unix 的基础。如果你不能非常轻松的使用它们,你将会被自己束缚住,因为它们构成了通过命令行和脚本与 Unix 系统交互的基础。
自己平常用到sed的场景一般都在shell中,自动化一些按部就班的东西,比如上一篇博文的自动生成django,在配置settings文件的时候难免修改或者增加一些设置。

注:以下用法如果用到 -i 参数 ,直接修改读取的文件内容,而不是输出到终端(危险动作)

1. 显示

1.1 以行为单位的显示

1
sed -n '5,7p' demo.txt

1.2 搜寻关键词显示

1
sed -n '/baird/p' demo.txt

-n :使用安静(silent)模式
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
关于指定内容搜寻并显示也可尝试选择grep命令,更好明白一点,例子在这。

2. 删除

两种方式与上面显示同理,只需将** p 改成 d **

3. 新增

增加有两种方式:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)

3.1 以行为单位的新增

1
sed '2a  new_line' demo.txt

2表示第二行,也可用2,5a表示二到五行

3.2 搜寻关键词新增

1
sed '/baird/i  new_line' demo.txt 

4. 替换

4.1 以行为单位的替换

c : 取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!倒是跟上面的新增差不多

1
sed '2,5c No 2-5 number' demo.txt

4.2 搜寻关键词替换

1
sed 's/要被取代的字串/新的字串/g

s: 每行,也可以选择固定在哪几行 1,20s/old/new/g
g: 一行上替换所有的匹配,不加表示只替换第一个,2表示替换第二个(场景很少)

5. 多点编辑

用的场景不多,sed写于shell脚本中,多写几行就是了

-e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作都将应用到模式缓冲区中的行上。因为是逐行进行多重编辑(即每个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果

1
sed -e action1 -e action2 

6. 记录自己遇到的几个坑问题

6.1 单双引号

自己平常用到sed的场景一般都在shell中,自动化一些按部就班的东西,比如上一篇博文的自动生成django,在配置settings文件的时候难免修改或者增加一些设置。

1
sed -i '/ALLOWED_HOSTS/c ALLOWED_HOSTS = \['\''*'\''\]' setting.py

注意到跟在sed后面的命令是用单引号的,如果我增加的文本中有本身有单引号,比如ALLOWED_HOSTS = ['*'],那么我们需要用'\''来表示单引号,当然还有一些其他方法比如啥十六进制\x27,记不太清了,但是这个一些太乱了。后来发现个更好的方法:
sed -i "/ALLOWED_HOSTS/c ALLOWED_HOSTS = \[\'*\'\]" settings.py
用双引号括起来,这样里面的单引号用转义符号表示\',简洁多了。

双引号还有个好处,就是里面可以直接更shell中的变量$xx
比如之前我是这么写的:

1
sed -i '/MIDDLEWARE/i LOCAL_APPS = \['\'''$app_name''\''\] \n' $Filename

可以直接这么写:

1
sed -i "/MIDDLEWARE/i LOCAL_APPS = \[\'$app_name\'\] \n" $Filename

上面的例子是替换的内容中包含引号,我们用\'来转义,但是如果查询的字符带有引号呢,是否同样要转义呢,答案是不需要!
比如下面这个例子,我们想要在唯一的'User':'xxxx'下一行添加一行'PASSWORD':'xxxx',前面不需要转义,而后面需要,这就是区别:

1
sed -i  "/'USER': '$p_user'/a  \        \'PASSWORD\': \'$p_password\',"  $Filename

**所以遇到修改单引号或者了要用变量时,尽量用双引号来操作sed
**

6.2 新增一行时增加空格或者Tab

1
sed -i "/common/i \    \'corsheaders.middleware.CorsMiddleware\'," $Filename

需要在i后面加一个\然后在加\t或者按几个空格

6.3 替换时如果变量里有/

1
sed -i "s/youdir/$Shell_folder/g"

达不到自己想要的状态,当遇到情况时可以选择整行替代!