sed (stream editor) 流编辑器, 对文本的每一行进行处理,处理后的结果输出到标准输出,而不会改变原文件。
用法:
sed 'command' $file (处理文件)
cat $file | sed 'command' (处理标准输出)
sed处理原理: 针对文本的每一行存储在一个缓冲区(pattern space)逐行进行处理,直到文件的末尾, 输出处理结果且不会改变源文件。
eg. 删除文件中包含字符“2”的行: >> sed '/2/d' $file
替换冒号面所有字符为空: >> sed 's/:.*$//' $file
打印包含kayword的行: >> sed '/keyword/p' $file
sed常用option:
-n: sed会把所有处理pattern space处理过的行输出, -n 只标准输出想要的输出的行
>> sed -n '/keyword/p' $file #只输出经过处理的行。其余的行不会输出到标准输出里。
-i : edit file in place. 原位修改文件
>> sed -i 's/abc/def/' $file 将文件里的abc修改成def并保存
-e : 设置多个command, -e 后面要直接加command,而不能再夹杂其他选项, 执行顺序按照command先后执行。
>> sed -n -e ‘1,2p’ -e ‘4p’ mysed.txt
Beijing 2003 Beijing 2004 Beijing 2006
-f : 设定command文件. 比较常用的匹配规则可以存到单独的文件中直接调用。
>> cat sed.cmd
/2003/,/2006/p
>> sed -n -f sed.cmd mysed.txt
Beijing 2003 Beijing 2004 Beijing 2005 Beijing 2006
sed的command范围指定和动作:
范围:
1) 按行数范围匹配:
’3,5‘ 匹配第3 4 5 行,
’5, $‘ 匹配第5指最后一行
>> sed -n '3,10p' $file 打印文件的第3-10 行内容。
2)按关键字匹配
’/^[^dD]/‘ 匹配行首不是d或D的行
3) 按包含关键字的行范围匹配
'/keyword1/,/keyword2/' 匹配包含keyword1的行至keyword2的行
>> cat $file
number1
number2
number3
number4
number5
number6
number5
>> sed '/number3/, /number5/p' $file #会输出至第一个number5出现的行结束。
number3
number4
number5
动作:
d 删除行 (delete)
p 打印行 (print)
sed -n '10,20p' test #显示 test 文件的第 10 行到第 20 行的内容
r 读取指定文件的内容 (read)
[roc@roclinux ~]$ cat ins.txt ====China==== #展示一下我们要处理的文件 [roc@roclinux ~]$ cat mysed.txt Beijing 2003 Beijing 2004 Beijing 2005 Beijing 2006 Beijing 2007 Beijing 2008 #看, 我们使用r来实现插入 [roc@roclinux ~]$ sed ‘/2005/r ins.txt’ mysed.txt Beijing 2003 Beijing 2004 Beijing 2005 ====China==== Beijing 2006 Beijing 2007 Beijing 2008
w 写入指定文件 (write)
#将包含2004、2005、2006的行保存到new.txt文件中 [roc@roclinux ~]$ sed ‘/200[4-6]/w new.txt’ mysed.txt Beijing 2003 Beijing 2004 Beijing 2005 Beijing 2006 Beijing 2007 Beijing 2008 #我们要的内容已经乖乖到碗里来了 [roc@roclinux ~]$ cat new.txt Beijing 2004 Beijing 2005 Beijing 2006
a 在下面插入新行新内容 (append)
#文件内容 [roc@roclinux ~]$ cat new.txt Beijing 2004 Beijing 2005 Beijing 2006 #我们希望在2004的下一行插入China [roc@roclinux ~]$ sed ‘/2004/a\China’ mysed.txt Beijing 2003 Beijing 2004 China Beijing 2005 Beijing 2006 Beijing 2007 Beijing 2008
i 在上面面插入新行新内容(insert)
[roc@roclinux ~]$ sed ‘/2004/i\China’ mysed.txt Beijing 2003 China Beijing 2004 Beijing 2005 Beijing 2006 Beijing 2007 Beijing 2008
s 替换(substitute)
sed '/^[dD]/s/x/X/g' test #将所有以 d 或 D 开头的行里的所有小写 x 字符变为大写 X 字符
# sed '/AA/s/BB/CC/g' $file 的语法格式,这表示我们要匹配到文件中带有 AA 的行,并且将这些行中所有的 BB 替换成 CC
sed 's/..$//' test #删除每行最后的两个字符
sed 's/..//' test #删除每行的前两个字符
y 逐字一一替换, 替换的字符长度需要与所替换的字符长度相同否则会报错。
y与s的区别:
- y 的语法格式是 y/source/dest/,表示将 source 中的字符对位替换为 dest 中的字符。而 s 的语法格式是 s/regexp/replacement/,表示通过正则匹配到的内容替换为 replacement 部分。
- y 只是简单的逐字替换,没有很多花样。s 支持 & 符号和预存储等特性,可以实现更多灵活的替换效果。
[roc@roclinux 20160229]$ sed 'y/ei/ie/' mysed.txt #逐个将文本里面的e换成i, i换成e. Biejeng 2003 Biejeng 2004 Biejeng 2005 Biejeng 2006 Biejeng 2007 Biejeng 2008
&符号的妙用,可以代表之前被匹配的部分
sed ’s/version/&2/‘ test #将文件中的version字符替换成version2 (就不需要重新打一遍了)
()符号: 小括号里面的内容会被预存储进\1 \2 \3 ...\N中,然后用\N来调用这些预存储的内容。
[roc@roclinux ~]$ echo "hello world" | sed 's/\(hello\).*/world \1/' world hello#将hello.*替换成world hello.
n 动作n实现隔行处理:
#原文件内容 [roc@roclinux ~]$ cat mysed.txt Beijing 2003 Beijing 2004 Beijing 2005 Beijing 2006 Beijing 2007 Beijing 2008 #我们同时使用了n动作和y动作 [roc@roclinux ~]$ sed ‘/200/{n;y/eijng/EIJNG/;}’ mysed.txt Beijing 2003 BEIJING 2004 Beijing 2005 BEIJING 2006 Beijing 2007 BEIJING 2008##这就是
n
选项在起作用,它的真实作用是将下一行内容放到处理缓存中,这样,就让当前这一行躲避开了替换动作,
refer to below tutorial: thanks for teaching~