- 论坛徽章:
- 0
|
ubuntu@ubuntu:~$ sed '/Public/R a' dat #R(read file),执行到包含Public的行时,
1 dat #从文件a中读入一行数据
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
@@@@@@@@ hello
9 Templates
10 Videos
命令:/b/t/T
:A,创建label A;
b A,跳转到label A处继续执行sed命令;
t A,本模式空间中,如果s///替换成功过,就跳转到label A处继续执行sed命令;没有替换成功,不执行跳转;
T A,跟t相反,本模式空间中,如果没有s///替换成功过,就跳转到label A处继续执行sed命令;替换成功,不执
行跳转;
以上三个跳转命令,如果没有跟label,且符合跳转条件时,都跳到脚本结尾;
ubuntu@ubuntu:~$ cat dat
1 dat
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed -n '/\<[dD]/b A #遇到包含以d或D开头的单词的行,就跳到A处把
/\<[P]/p #包含以d开头的单词的行打印出来
:A #同时打印包含以P开头的单词的行
/\<[d]/p #
' dat #相当于 if (包含 d/D开头的单词)
1 dat # goto A
3 dir1 # else if (P开头)
7 Pictures # 打印
8 Public # :A 打印d开头的单词所在的行
ubuntu@ubuntu:~$ sed -n '/\<[dD]/b # 遇到包含以d或D开头的单词的行,
/\<[P]/p #跳转到脚本结尾
:A #打印包含以P开头的单词的行
/\<[d]/p
' dat
7 Pictures
8 Public
# 命令t
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; t A #如果dir替换成功,
/dir/a\***** #就跳到:A处,打印出来
:A #否则顺序执行下面的脚本
/\<[d]/p
' dat
1 dat
3 dir@@@@@@1
4 dir@@@@@@2
ubuntu@ubuntu:~$ sed -n 's/DIR/dir@@@@@@/; t A #DIR没有替换成功,就不跳转,
/dir/a\***** #顺序执行下面的脚本
:A
/\<[d]/p
' dat
1 dat
3 dir1
*****
4 dir2
*****
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; t #如果dir替换成功,
/dir/a\***** #就跳到脚本结尾,不打印出来
:A
/\<[d]/p
' dat
1 dat
ubuntu@ubuntu:~$ sed -n -r 's/DIR/dir@@@@@@/; t #DIR没有替换成功,就不跳转,
/dir/a\***** #顺序执行下面的脚本
:A
/\<[d]/p
' dat
1 dat
3 dir1
*****
4 dir2
*****
#命令T
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; T A #dir替换成功,不跳转,
/dir/a\***** #顺序执行下面的脚本
:A #在包含dir的行后添加*****
/\<[d]/p
' dat
1 dat
3 dir@@@@@@1
*****
4 dir@@@@@@2
*****
ubuntu@ubuntu:~$ sed -n 's/DIR/dir@@@@@@/; T A #DIR没有替换成功,跳转到A,
/dir/a\***** #打印出包含[以d开头的字母]的行
:A
/\<[d]/p
' dat
1 dat
3 dir1
4 dir2
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; T #dir替换成功,不跳转,
/dir/a\***** #顺序执行下面的脚本
:A
/\<[d]/p
' dat
3 dir@@@@@@1
*****
4 dir@@@@@@2
*****
ubuntu@ubuntu:~$ sed -n 's/DIR/dir@@@@@@/; T #DIR没有替换成功,
/dir/a\***** #跳转到脚本结尾,不打印任何行
:A
/\<[d]/p
' dat
# 命令n/N, d/D
多行Next(N)命令是相对于next(n)命令的,
n(next)命令将模式空间中的内容输出,清空模式空间,然后读入下一行,然后继续执行sed脚本(并不会转移到脚本开头)
N(Next)命令则保存原来模式空间中的内容,再把新的一行读入,两者之间依靠一个换行符"\n"来分隔,然后继续执行sed脚本。
ubuntu@ubuntu:~$ cat dat
1 dat
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed -n '/Documents/n #遇到Documents所在的行,输出模式空间(因为使用
/M/p #了n选项,并不会输出),清空模式空间,读入下一行
' dat #读入的内容中刚好包含了”M”,就打印出来
6 Music
ubuntu@ubuntu:~$ sed -n '/Documents/N #遇到Documents所在的行,把下一行数据添加在
/M/p #模式空间后面(两行之间自动添加\n分隔),
' dat #现在模式空间包含”M”, 打印模式空间
5 Documents #p打印整个模式空间,
6 Music #P打印模式空间第一个\n前的内容
ubuntu@ubuntu:~$ sed -n '/Documents/{ #遇到Documents所在的行,把下一行数据添加在
N #模式空间后面(两行之间自动添加\n分隔),
d} #删除模式空间内容,
/Music/p
' dat
ubuntu@ubuntu:~$ sed -n '/Documents/{ #遇到Documents所在的行,把下一行数据添加在
N #模式空间后面(两行之间自动添加\n分隔),
D} #删除模式空间中第一个\n前的内容,
/Music/p #打印模式空间
' dat
6 Music
前面我们说过,sed执行其实就是个大循环,每次对一行数据进行操作,一行一行的将所有的数据处理完。
对每一行操作,sed有4个步骤:
1、读入当前行数据
2、对其执行sed命令
3、输出模式空间的内容(除非-n限制了自动输出)
4、清空模式空间
# 命令h/H, g/G
h/H 将模式空间的内容copy(覆盖原有内容)/append到存储空间
g/G 将存储空间的内容copy(覆盖原有内容)/append到模式空间
H(Hold)/G(Get),都会在目的空间的原有内容之后加上一个换行符“\n”,然后才把源空间中的内容加到换行符的后面。
ubuntu@ubuntu:~$ sed -n '/dir/{h;d} #将dir所在的行copy到(覆盖)存储空间(dir有两次)
/Doc/{g;p}' dat #在Doc这一行,取出存储空间的内容,覆盖模式空间
4 dir2 #打印模式空间
ubuntu@ubuntu:~$ sed -n '/dir/{h;d} #将dir所在的行copy到(覆盖)存储空间(dir有两次)
/Doc/{G;p}' dat #在Doc这一行,取出存储空间的内容,附加在模式空间
5 Documents #打印模式空间
4 dir2
ubuntu@ubuntu:~$ sed -n '/dir/{H;d} #将dir所在的行附加到存储空间(dir有两次)
/Doc/{g;p}' dat #在Doc这一行,取出存储空间的内容,覆盖模式空间
#注意,这个空行不是我手动换的,是本命令的输出哦
3 dir1
4 dir2
ubuntu@ubuntu:~$ sed -n '/dir/{H;d} #将dir所在的行附加到存储空间(dir有两次)
/Doc/{G;p}' dat #在Doc这一行,取出存储空间的内容,附加在模式空间
5 Documents #打印模式空间
#怎么也有个空行?
3 dir1
4 dir2
ubuntu@ubuntu:~$ cat dat # 命令x,交换模式空间和存储空间的内容
1 dat
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed '/Doc/{h;d} #遇到包含Doc的行,就把模式空间的内容
/Pic/x #放进存储空间,然后删除模式空间;
' dat #这样Doc所在的行,是不会显示出来的
1 dat
2 Desktop #所以第4行后直接就是第6行
3 dir1
4 dir2
6 Music
5 Documents #遇到包含Pic的行(第7行)后,交换模式空间和
8 Public #存储空间的内容,
9 Templates
10 Videos
下面的例子中请注意命令p/l/P的差别
ubuntu@ubuntu:~$ sed -n '/\<D/{N;p}' dat #遇到包含以D开头的单词的行,
2 Desktop #就读取下一行到模式空间, 然后打印模式空间
3 dir1
5 Documents
6 Music
ubuntu@ubuntu:~$ sed -n '/\<D/{N;l}' dat #l,以可见(visually unambiguous)的方式
2 Desktop\n3 dir1$ #查看模式空间的内容,
5 Documents\n6 Music$ #模式空间的内容实际上是左边这个样子的
ubuntu@ubuntu:~$ sed -n '/\<D/{N }' dat #P,打印模式空间中第一个换行符号之前的内容
2 Desktop
5 Documents
[ubuntu@bourne ~]$ cat dat1
hello Tom, hello Michel, hello Sara
hello Bourne, hello Ellen, hello Marco
[ubuntu@bourne ~]$ sed 's/hello/hi/' dat1 #将每个模式空间(行)中第一个hello替换为hi
hi Tom, hello Michel, hello Sara
hi Bourne, hello Ellen, hello Marco
[ubuntu@bourne ~]$ sed 's/hello/hi/g' dat1 #g(global),
hi Tom, hi Michel, hi Sara #将每个模式空间(行)中所有的hello替换为hi
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's#hello#hi#g' dat1 #s#...#...#g 可以用别的分割符号
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's hello hi g' dat1 #s ... ... g
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's-hello-hi-g' dat1 #s-...-...-g
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's)hello)hi)g' dat1 #s)...)...)g
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
ubuntu@ubuntu:~$ sed -n -r '/Pub/{N #将模式空间的内容写入文件b
w b #遇到包含Pub的行时,将下一行的内容添加到模式空间
}' dat #模式空间的内容为:8 Public\n9 Templates
ubuntu@ubuntu:~$ cat b
8 Public
9 Templates
ubuntu@ubuntu:~$ sed -n -r '/Pub/{N #将模式空间中第一个换行符号之前的内容写入文件b
W b
}' dat
ubuntu@ubuntu:~$ cat b
8 Public
#大小写转换的经典用法
ubuntu@ubuntu:~$ sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' dat
1 DAT #y,直译,将[a-z]依次替换为[A-Z],
2 DESKTOP #本例将小写字母全部转换为大写字母
3 DIR1
4 DIR2
5 DOCUMENTS
6 MUSIC
7 PICTURES
8 PUBLIC
9 TEMPLATES
10 VIDEOS
ubuntu@ubuntu:~$ sed 'y/abcdefghijklmnopqrstuvwxyz/qazxswedcvfrtgbnhyujmkiolp/' dat
1 xqj #将[a-z]依次替换为[qazxsw...olp]
2 Dsufjbn #这样就成了一个简单的加密器
3 xcy1 #y/明文串/密文串/
4 xcy2 #注意,明文串和密文串中都不能出现相同的字母、
5 Dbzmtsgju #数字、符号,前后两个串的长度要相等
6 Mmucz
7 Pczjmysu
8 Pmarcz
9 Tstnrqjsu
10 Vcxsbu
ubuntu@ubuntu:~$ sed 'y/abcdefghijklmnopqrstuvwxyz/qazxswedcvfrtgbnhyujmkiolp/' dat > tmp
ubuntu@ubuntu:~$ sed 'y/qazxswedcvfrtgbnhyujmkiolp/abcdefjhijklmnopqrstuvwxyz/' tmp
1 dat #将明文串和密文串交换位置,就成了解码器
2 Desktop #y/密文串/明文串/
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed -n '/\w{3}[12]{1}/p' dat
ubuntu@ubuntu:~$ sed -n -r '/\w{3}[12]{1}/p' dat # r,使用扩展正则表达式时,要加-r选项
3 dir1
4 dir2
|
|