Back to Unix-like Utilities

See also grepawkVim

Sed - A Stream editor

sed(stream editor)是Unix常见的命令行程序。sed用来把文档或字符串里面的文字经过一系列编辑命令转换为另一种格式输出。sed通常用来匹配一个或多个正则表达式的文本进行处理。

分号(;)可以用作分隔命令的指示符。

1. gnu-sed on OS X

➜  ~  brew install gnu-sed --with-default-names
➜  ~  vi ~/.zshrc
# add for gun-sed
PATH="/usr/local/opt/gnu-sed/bin:$PATH"
MANPATH="/usr/local/opt/gnu-sed/libexec/gnuman:$MANPATH"
➜  ~  brew install homebrew/dupes/grep --with-default-names
# add for gun-grep
PATH="/usr/local/opt/grep/bin/:$PATH"
➜  ~  sed --version
sed (GNU sed) 4.2.2
➜  ~  grep --version
grep (GNU grep) 2.21

2. Commands Helper

  -e script, --expression=script #-e可以不加,在没有-e -f的时候,sed后面第一个非option的参数就被作为script读入进来
                 add the script to the commands to be executed

  -f script-file, --file=script-file
                 add the contents of script-file to the commands to be executed

  -i[SUFFIX], --in-place[=SUFFIX] #编辑模式,变化会更新到文件中
                 edit files in place (makes backup if SUFFIX supplied)

  -r, --regexp-extended #正则扩展模式
                 use extended regular expressions in the script.

2.1. 基础命令行格式

Sed 命令列可分成编辑指令与文件路径两部分。其中,编辑指令负责控制所有的编辑工作;文件路径是要编辑的文件的路径。

sed编辑指令均由位址(address)与函数(function)两部份组成。其中,在执行时,sed利用它的位址参数来决定编辑的对象,而用它的函数参数编辑。

[address1[,address2]]function[argument]

address1和address2是地址参数,可以是行数或regular expression字串 , 表示所执行编辑的资料行;

函数参数 function[argument] 为 sed 的内定函数 , 表示执行的编辑动作。

2.2. 常用的sed命令

2.3. 函数解释

函数参数    功能  
: label   建立script file内指令互相参考的位置
#         注释  
{ }       集合有相同位址参数的指令
!         不执行函数参数
=         印出资料行数( line number )
a\        添加使用者输入的资料
b label   将执行的指令跳至由 : 建立的参考位置
c\        以使用者输入的资料取代资料。  
d         删除资料。   
D   删除 pattern space 内第一个 newline 字母 \ 前的资料。   
g   拷贝资料从 hold space。   
G   添加资料从 hold space 至 pattern space 。   
h   拷贝资料从 pattern space 至 hold space 。   
H   添加资料从 pattern space 至 hold space 。   
l   印出 l 资料中的 nonprinting character 用 ASCII 码。   
i\   插入添加使用者输入的资料行。   
n   读入下一笔资料。   
N   添加下一笔资料到 pattern space。   
p   印出资料。   
P   印出 pattern space 内第一个 newline 字母 \ 前的资料。   
q   跳出 sed 编辑。   
r   读入它档内容。   
s   替换字串。   
t label   先执行一替换的编辑指令 , 如果替换成牛p>则将编辑指令跳至 : label 处执行。   
w   写资料到它档内。   
x   交换 hold space 与 pattern space 内容。   
y   转换(transform)字元。

2.4. 正则表达式

Overview of Regular Expression Syntax

*
    Matches a sequence of zero or more instances of matches for the preceding regular expression, but many nonGNU implementations do not support this and portable scripts should instead use \* in these contexts. Such as OS X.
.
    Matches any character, including newline.
^
    Matches the null string at beginning of the pattern space, i.e. what appears after the circumflex must appear at the beginning of the pattern space. 
\+
    As *, but matches one or more. It is a GNU extension.
\?
    As *, but only matches zero or one. It is a GNU extension. 

2.4.1. Examples

‘[a-zA-Z0-9]’
    In the C locale, this matches any ASCII letters or digits.

‘[^ tab]\+’
    (Here tab stands for a single tab character.) This matches a string of one or more characters, none of which is a space or a tab. Usually this means a word.

‘[^]]\+’
    任何不是]的字符

2.4.2. Extended Regular Expressions

http://www.grymoire.com/Unix/Regular.html#uh-12

egrep 和 awk 都使用扩展的正则表达式。?是0或1次匹配,+是1或更多的字符集合

3. Samples

3.1. substitution command: s

s means [sʌbstɪ'tjuːʃn] n. 代替;[数] 置换;代替物

# 只匹配到每行的第一个
➜  ~ echo day day | sed s/day/night/ 
night day
# 全行统配: g命令
➜  ~ echo day day | sed s/day/night/g
night night
# old文件中的内容被替换后更新成new文件
➜  ~ sed s/day/night/ old > new 

3.1.1. delimiter

[dɪ'lɪmɪtə] n. [计算机]定义符;定界符.

替换命令中通常用斜杠来做界定符(/../../)。当做以下替换的时候就比较难看了,这时候我们可以换一个字符来做界定符

➜  ~ echo /usr/local/bin/sed |sed 's/\/usr\/local\/bin/\/common\/bin/'
/common/bin/sed
➜  ~ echo /usr/local/bin/sed |sed 's:/usr/local/bin:/common/bin:'
/common/bin/sed

3.2. 替换并修改文件(-i)

# 替换某行内容(OS X下用\*)
➜  /tmp  sed -i.bak s/^abc=.\*/abc=123.45.6.7/g a && cat a && diff a a.bak
#abc=fds
abc=123.45.6.7
2c2
< abc=123.45.6.7
---
> abc=123.45.6.8

echo 'android:versionName="1.0.0" android:versionCode="1"' | sed 's/versionCode=*"[0-9][0-9]*"/versionCode="2"/; s/versionName="[^"][^"]*"/versionName="1.2.0"/'

uname -s # linux
sed -i 's#http://test.li3huo.com/api.jsp#http://li3huo.com/channel.jsp#g' config.xml

3.3. 显示区间的内容

sed -n '190,196p' song.txt

3.4. matching

Refer here

➜  fabric  echo 'Requests per second:    15.13 [#/sec] (mean)' |sed -n 's/^Requests per second:    \(.*\)\[.*/\1/p'
15.13 
➜  tmp  sed -n 's/^Requests per second:    \(.*\)\[.*/\1/p' ab_on_s3_tk.1426756468.07 
30.42
➜  tmp  seq 6|sed -n '/.*/{/[1-5]$/!p}'  
6
➜  tmp  echo '80/tcp -> 0.0.0.0:32769'|sed -n 's/80\/tcp -> 0.0.0.0:\(.*\)/\1/p'
32769

3.4.1. the matched string: &

# * matches zero or more 
➜  ~ echo "abc 123" | sed 's/[0-9]*/(&)/'     
()abc 123
➜  ~ echo "abc 123" | sed 's/[0-9]*/(&)/g'
()a()b()c() (123)
➜  ~ echo "abc 123" | sed 's/[0-9][0-9]*/(&)/'
abc (123)
➜  ~ echo "abc 123" | sed -r 's/[0-9]+/(&)/g'
abc (123)

3.4.2. the matched pattern: \1

➜  ~ echo abcd123 | sed 's/\([a-z]*\).*/\1/'
abcd
➜  ~ echo abcd123 def456 | sed 's/\([a-z]*\).* \([a-z]*\).*/\2 \1/'
def abcd

3.4.3. pattern flag: ^

➜  ~ echo '   abc   ' |sed 's/[^ ][^ ]*/(&)/'
   (abc)  

4. Reference

MainWiki: sed (last edited 2015-08-31 21:02:24 by twotwo)