Board logo

标题: [原创教程] 一起来学习强大的sed(连载) [打印本页]

作者: batman    时间: 2008-9-24 20:37     标题: 一起来学习强大的sed(连载)

本人找到的功能较全的sed.exe 4.14 http://bbs.bathome.net/thread-1114-1-1.html
注:本人是sed新手,下面所叙述的也是本人的学习心得,还请大家补充和指正
有文本a.txt内容如下:
  1. a-1
  2. a-2
  3. a-3
  4. 1-a
  5. 2-a
  6. 3-a
  7. b-1
  8. b-2
  9. b-3
复制代码
1、显示所有含有字符"a"的行
  1. sed -n "/a/p" a.txt
复制代码
-n开关是表示输出由编辑指令控制,p开关是有条件显示开关,在些处就是仅显示有"a"字符的行。
2、显示所有以字符"a"开头的行
  1. sed -n "/^a/p" a.txt
复制代码
符号"^"在这里不是起到转义的作用而是表示行的开始,这个和findstr中的用法是一样的。
3、不显示所有含有"a"字符的行
  1. sed "/a/d" a.txt
复制代码
d开关是表示删除的意思。
4、不显示所有以"a"字符开头的行
  1. sed "/^a/d" a.txt
复制代码
5、将文本中所有的"b"字符替换为"bathome"
  1. sed "s/b/bathome/" a.txt
复制代码
s开关是替换开关,开启此开关后将会将第一个//间的字符替换为第二个//间的字符。
6、将文本中以"a"开头的行全部替换为"bathome"
  1. sed "s/^a.*/bathome/" a.txt
复制代码
7、不显示文本中前5行
  1. sed 1,5d a.txt
复制代码
即为删除文本前期前5行。
8、显示文本中5-8行
  1. sed -n 5,8p a.txt
复制代码
一样的要用-n开关先将输出定向到编辑指令控制。
9、将文本中所有"a"替换为"A",同时删除所有含有字符"-1"的行,并将所有以"b"开头的行替换为"bathome"
  1. sed -e "s/a/A/" -e "/-1/d" -e "s/^b.*/bathome/" a.txt
复制代码
-e开关是sed中多个命令的连接开关。
10、删除除了以"3"字符打头的行以外的所有行
  1. sed "/^3/!d" a.txt
复制代码
!开关是表示以什么样的条件不执行命令,在这里就是碰到以"3"字符打头的行不执行删除命令。

[ 本帖最后由 Batcher 于 2009-5-1 21:09 编辑 ]
作者: Batcher    时间: 2008-9-24 21:39

第5点,关于s的解释,可能这样更准确:
sed 's/foo/bar/' # replaces only 1st instance in a line
sed 's/foo/bar/4' # replaces only 4th instance in a line
sed 's/foo/bar/g' # replaces ALL instances in a line
sed '1s/foo/bar/' # replaces only 1st instance in 1st line

作者: batman    时间: 2008-9-24 22:12     标题: 连载二

a.txt内容如下:
  1. 1-a a-1 aa
  2. 2-a a-2 aa
  3. 3-a a-3 aa
  4. 4-a a-4 aa
  5. 5-a a-5 aa
复制代码
11、将文本中每行第二个"a"替换为"b"
  1. sed "s/a/b/2" a.txt
复制代码
12、将文本中每行所有的"a"替换为"b"
  1. sed "s/a/b/g" a.txt
复制代码
13、将文本中第1-3行中第三个"a"替换为"b"
  1. sed "1,3s/a/b/3" a.txt
复制代码
14、将文本中第3-5行中第一、三个"a"替换为"b"
  1. sed -e "3,5s/a/b/1" -e "3,5s/a/b/3" a.txt
复制代码
15、除了第四行外将所有行的第二个"a"替换为"b"
  1. sed "4!s/a/b/2" a.txt
复制代码

作者: batman    时间: 2008-9-25 23:44     标题: 连载三

a.txt内容如下:
  1. 1:basktop at time to door
  2. 2:basktop at time to door
  3. 3:bathome is webbbs
  4. 4:you can not do it
  5. 5:yes you need to watch the game
  6. 6:he is write for bat
  7. 7:he is write for bat
  8. 8:you can not do it
复制代码
16、删除文本中所有的空行
  1. sed "/^$/d" a.txt
复制代码
"^"表示行的开始,"$"表示行的结束,用"^$"就表示空行,用d开关将所有的空行删除。
17、删除文本最后一行
  1. sed $d a.txt
复制代码
也可先用n开关来将输出定向到编辑指令,然后用p开关来显示所有的
行,并用$!来屏蔽最后一行:sed -n $!p a.txt。
18、删除文本中第2行到第一个"write"所在行之间所在的所有内容(含这个"write"所在行)
  1. sed "2,/write/d" a.txt
复制代码
19、在含有"need"字符的所在行后插入"批处理"字符(另起一行)
  1. sed "/need/a\批处理" a.txt
复制代码
a开关是表示在文本中插入内容,后面必须要跟上"\"
20、在文本中每行后插入"批处理"字符(另起一行)
  1. sed "a\批处理" a.txt
复制代码
当a开关前没有任何条件限制时"\"后面所跟的任何字符将被当做插入内容而通篇插入。
21、在文本中每行前插入"批处理"字符(前一行)
  1. sed "i\批处理" a.txt
复制代码
22、在文本中含有"write"字符的行前插入"批处理"字符(前一行)
  1. sed "/write/i\批处理" a.txt
复制代码
i开关的作用和a开关相似,只是插入的位置是一前一后。
23、显示文本的奇数行(含空行)
  1. sed -n -e "p" -e "n" a.txt
复制代码
在sed中用n表示奇数行,用p表示偶数行。
24、显示文本的偶数行(含空行)
  1. sed -n -e "n" -e "p" a.txt
复制代码
在此处只会显示7行空行。
25、统计行数
  1. sed -n "$=" a.txt
复制代码
这个没有多说的,大家记住就好了。

[ 本帖最后由 batman 于 2008-9-26 11:49 编辑 ]
作者: batman    时间: 2008-9-26 00:48     标题: 连载四

a.txt内容如下:
  1. we he she they
  2. we he she they
  3. they our his him my
  4. we he she they
  5. my me you your her
  6. they our his him my
复制代码
26、将指定字符进行变形
  1. sed "s/\(t\)\(h\)\(e\)\(y\)/\4\1\3\2/" a.txt
复制代码
在这里所有"\'都是转义符,而\4就代表前面字符串中的第4个字符,其它以此类推,再用s开关进行替换,就达到了将字符进行变形的目的,如是4321的顺序则将指定字符进行了反转。
27、将整行字符进行反转
  1. sed "/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//" a.txt
复制代码
关于这个本人也没有理解过来,大家先死记住就好了。
28、删除重复行(保留本行)
  1. sed -n "G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P" a.txt
复制代码
一样是死记,本人觉得不如bat。
29、显示3的倍数行
  1. sed -n "n;n;p" a.txt
复制代码
先用n开关将输出定向到编辑指令,然后输入法3-1个n;最后用显示开
关p结尾,也就时说3前的数字的倍数行不显示,只显示3的倍数行。
30、在所有的行下加上行号将在行号加上字符":"
  1. sed "/./=" a.txt|sed "/./N; s/\n/:/"
复制代码
这是sed的一个正则表达式,先是自己定义/./的值是a.txt,这个是必须定义的,如直接写成sed "/a.txt/n;s/\n/:/"是会出错的,后面的s/\n/:/是表示用":"来做分隔符,如省去则会默认将一个空行来做为分隔符,这样行号就变成了插入在本行前面了,";"是个命令连接符。
31、在行首插入字符(含空格)
  1. sed "s/^/bathome/" a.txt
复制代码
其实就是用s开关将行首的空字符替换为要插入的字符,那么在行尾增加字符便可写成sed "s/$/bathome/" a.txt。
32、在每行后增加一空行
  1. sed G a.txt
复制代码
不多说了,这个简单好记。
33、在每行后增加5行空行
  1. sed "G;G;G;G;G;G" a.txt
复制代码
这个好理解,增加多少行就写多少个G;最后用G结束。
34、在含有"me"字符的行后增加一空行
  1. sed "/me/G" a.txt
复制代码
35、在含有"me"字符的行前增加一空行
  1. sed "/me/{x;p;x;}" a.txt
复制代码
这个比较复杂点,大家只要记住这种用法就好了。

[ 本帖最后由 batman 于 2008-9-26 11:50 编辑 ]
作者: batman    时间: 2008-9-26 01:40     标题: 连载五

文本a.txt内容如下
  1. 123456789
  2. abcdefg
  3. gfabced
  4. 1790562.4345
  5. 批处理 bat
复制代码
36、将文本右对齐
  1. sed -e :a -e "s/^.\{1,79\}$/ &/;ta" a.txt
复制代码
在这里":a"是sed在每行行首设立的用来跳转的标签,再由后面的t开关来检测在
本行命令是否执行完,没有执行完则继续执行,执行完了则跳转到下一个:a标签
处(也就是跳到下一行),这就其实是一个循环了,同时要说明一下的是"&"是表
示的前面命令中保存的字符也就是每行原有的字符,前面的" "则是自动在行前补
空格,当然我们也可以改成任意字符。另要说明的虽然默认的一行有80个字符,
但在这里最多只能设为79,当然这个数字我们也可以修改。
37、将文本内容居中
  1. sed -e a: -e "s/^.\{1,79\}$/ & /;ta" a.txt
复制代码
如果大家理解了上面36中的命令,相信这个命令就没问题了,同理将本来不是左
对文的文本进行左对齐也就没问题了。
38、显示文本含有数字的行
  1. sed -n "/[0-9]/p" a.txt
复制代码
这一用法和findstr极为相似,同理删除含数字行就是sed "/[0-9]/d" a.txt。
39、将文本中的字母换成大写
  1. sed "y/abcdefg/ABCDEFG/" a.txt
复制代码
y开关是sed中真正的变形开关,同理可以将文本中的数字全变成大写数字。
40、将文本中数字加上,分隔符
  1. sed -e :a -e "s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta" a.txt
复制代码
这也是一个循环。
作者: batman    时间: 2008-9-26 13:24     标题: 连载六

有a.txt内容如下:
  1. 1:When I was a little girl, I found love in a box all because of a class assignment.
  2. 2:On a Friday night I made an announcement at the dinner table.
  3. 3:The words bubbled out in a torrent of excitement I could no longer contain.
  4. 4:“My teacher said we have to bring a box for our valentines on Monday.
  5. 5:But it has to be a special box, all decorated.”
  6. 6:Mother said, “We’ll see,” and she continued eating.
  7. 7:I wilted faster than a flower with no water.
  8. 8:What did “We’ll see” mean?
  9. 9:I had to have that box or there would be no valentines for me.
  10. 10:My second grade Valentine’s Day would be a disaster.
复制代码
41、根据用户输入的内容"pause"来取代第5-8行所有的内容(非每行)
  1. sed "5,8c\pause" a.txt
复制代码
c开关是sed中用用户输入内容来取代原本内容的,其后紧跟"\",用这种方法同样可以将指定行替换为空行(并不是严格意义上的空行,至少有一个空格),如:sed "9c\ " a.txt。
42、根据用户输入的内容"pause"来取代文本所有的行
  1. sed "1,$c\pause" a.txt
复制代码
1,$表示的是从第一行到最后一行
43、删除文本所有行首的四个字符
  1. sed "s/^....//" a.txt
复制代码
其实就是将行首的四个字符替换为空。
44、删除文本所有行尾的四个字符
  1. sed "s/....$//" a.txt
复制代码

45、将文本行右移四个字符位
  1. sed "s/^/    /" a.txt
复制代码

即将行首(实际是一个空字符)替换为四个空格,也就在每行前加入了四个空格而将行右移了四位。

[ 本帖最后由 batman 于 2008-9-26 13:29 编辑 ]
作者: Batcher    时间: 2008-9-26 15:26

Vkill兄的网站上有sed4.1.4的单行本
http://www.vkill.net/tools.html
作者: yslyxqysl    时间: 2008-9-30 21:21

看来sed真的非常强大。
作者: batman    时间: 2008-10-6 17:05

连载七
大家如果使用了本人在顶楼提供的sed,会发现其帮助信息是纯英文版的,实际上现在网
上能找到的sed版本,其帮助信息都是没有经过翻译的,于是,本人特将其帮助信息进行
了汉译整理并对照如下(不能说是翻译,因为有的信息直译过来根本是讲不通的)
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...
用法:sed[选项]...{脚本-如果没有其它脚本}[输入文件]
  -n, --quiet, --silent
  -n, --安静模式
                 suppress automatic printing of pattern space
     禁止自动输出模本空间(意即将输出定向到由命令控制)
  -e script, --expression=script
  -e 脚本,--表达式=脚本
                 add the script to the commands to be executed
     添加脚本的命令将被执行(-e是个命令连接开关,在第二个-e前第一个-e后的命令将首先被执行完,意即执行完一条命令后再执行后面的命令)
  -f script-file, --file=script-file
  -f 脚本文件        
                 add the contents of script-file to the commands to be executed
     从文本中读取命令并执行
  -i[suffix], --in-place[=suffix]
  -i[后缀]
                 edit files in place (makes backup if extension supplied)
     在符合条件的文本行后添加指定内容(之前是-a)
  -l N, --line-length=N
  -l N,--线长度=N
                 specify the desired line-wrap length for the `l' command
     用-l N语法来指定线(字符数,循环次数,行数)长度
  -r, --regexp-extended
  -r, --表达式延展
                 use extended regular expressions in the script.
                 扩展脚本中的正则表达式
  -s, --separate
  -s,--分割替换
                 consider files as separate rather than as a single continuouslong stream.
     将文本行分割为单独的字符串来进行替换
  --text     switch to text mode
  --text     切换到文本模式
  -u, --unbuffered
 -u,--无缓冲
                 load minimal amounts of data from the input files and flushthe output buffers more often
              从输入文件中加载数据并保持输出的刷新(非常用语法)    
      --help     display this help and exit
   --help  显示帮助信息
  -V, --version  output version information and exit
  -V, --版本 输出版本信息
  If no -e, --expression, -f, or --file option is given, then the firstnon-option argument is taken as the sed script to interpret.  All remaining arguments are names of input files; if no input files arespecified, then the standard input is read.
  如果没有-e开关,表达式,-f开关,或者给出的文件选项,那么将会首先输出sed脚本的帮助信息,如果仅仅是后面没有输入文件,那么程序将会接收使用者键盘输入的指令。
  E-mail bug reports to: [email]bonzini@gnu.org[/email] .
  Be sure to include the word ``sed'' somewhere in the ``Subject:'' field.
  报错电子信箱:bonzini@gnu.org。
  请务必在邮件(标题)中注明“sed”“来自于那个领域”的关键词。

[ 本帖最后由 batman 于 2008-10-6 17:08 编辑 ]
作者: pusofalse    时间: 2008-10-6 23:52

看着头都大了~
想知道sed中有无perl风格的正则表达式元字符用法,比如用\r表示一个回车 \n表示一个换行,\d+能匹配至少有一个数字的纯数字串等~

[ 本帖最后由 pusofalse 于 2008-10-11 19:25 编辑 ]
作者: i9420    时间: 2008-10-31 20:57

我用他输入13-20的文字到另外一个文件,但是生成的文件之间有一个ctr+v生成的黑点,如何去掉??
作者: a590687    时间: 2010-1-21 16:58

sed 输出的黑点着实烦人, 一直没找到解决办法,
即使换了字体看不到黑点,也无法正常换行.
作者: Batcher    时间: 2010-1-21 17:49     标题: 回复 13楼 的帖子

试试4.14版:
http://bbs.bathome.net/thread-1114-1-1.html
作者: a590687    时间: 2010-1-21 19:24     标题: 30行

  1. sed "/./=" a.txt|sed "/./N; s/\n/:/"
  2. ::管道命令前面是把每行前插入一行 存放行号
  3. ::管道命令后面是在之前的命令结果基础上,把插入的行号之后的换行符替换成":"
复制代码
  1. sed "/./=" a.txt|sed "/./n; s/\n/:/"
  2. ::如果把N换成n 的话 管道命令后面的sed不会执行也就是没有替换成功
  3. ::这里只显示管道命令前面的命令结果
复制代码
为什么呢? 区分大小写?
而且 命令执行正确的话 不是在行后插入行号
格式是:
      行号:行内容

[ 本帖最后由 a590687 于 2010-1-21 19:30 编辑 ]
作者: a590687    时间: 2010-1-21 19:27     标题: 回复 14楼 的帖子

暂时:XPsp3深度精简版系统 咱们论坛的1.14用不了. 网上下的大概说是1.15. 能用不过就是有黑块.

还有就是我这个 sed替换和删除...可以更改文件内容的命令并不会真的改变文本内容,只是在cmd上输出的时候有所改变.  应该是sed不能正常使用的原因? 求解.

[ 本帖最后由 a590687 于 2010-1-21 20:25 编辑 ]
作者: Batcher    时间: 2010-1-21 21:26     标题: 回复 16楼 的帖子

sed命令默认是不会修改文件本身的,除非使用-i开关。
作者: a590687    时间: 2010-1-22 09:08     标题: 回复 17楼 的帖子

试了一下 -i开关 真是啊,我还没学习到这里.嘿嘿.  继续看 哪天换SP2系统把黑块问题解决了
作者: Batcher    时间: 2010-1-22 13:18     标题: 回复 18楼 的帖子

换系统的时候别在选择精简版、家庭版等阉割系统了^_^
作者: a590687    时间: 2010-1-22 19:58

Batcher 大哥,嘿嘿. 因为电脑里程序太多, 还有java和ps等等工具安装很麻烦.咱还是老电脑
所以俺想到一个解决黑块的方法. 就是在用到sed输出的时候 在CMD上复制再粘到文本里,
哈哈!!!  真是灵机一动啊.
作者: yxw030826    时间: 2010-1-24 23:01

有点像shell中的sed的不知道有没有强大的awk啊
作者: wolfsnow    时间: 2010-4-14 11:06     标题: sed有缺陷

不好意思,成功了。我输入错误。

[ 本帖最后由 wolfsnow 于 2010-4-14 11:07 编辑 ]
作者: Batcher    时间: 2010-4-14 14:20     标题: 回复 21楼 的帖子

这个,可以有:
http://bbs.bathome.net/thread-1114-1-1.html
http://bbs.bathome.net/thread-3997-1-1.html
作者: Batcher    时间: 2010-4-14 14:22     标题: 回复 20楼 的帖子

可以把sed的结果用管道传递个more,然后再重定向输出到文件。
作者: Hello123World    时间: 2011-6-14 16:49

本帖最后由 Hello123World 于 2011-6-22 16:22 编辑

看到连载2。
我想问一下楼主,你学sed命令是通过什么资料来学的,不会是通过sed自带的帮助吧——看的头疼,全英文。
看到连载3.(这得多重复看几遍,看完连载2,发现连载1忘得差不多了……)
看到连载4.
作者: batman    时间: 2011-6-14 17:08

25# Hello123World
正是如此再加多练习。。。

ps:我的sed并不怎么样。。。
作者: zheng2012    时间: 2013-1-21 18:54

管理员联系QQ多少呢
作者: xslxslxsl    时间: 2013-3-28 21:35

很不错,学习了,谢谢!
作者: taofan712    时间: 2017-3-6 11:34

本帖最后由 taofan712 于 2017-3-6 11:59 编辑

拜读帖子后感觉修为快要突破元婴境了,原来sed也有简单的一面。
表达式加不加双引号的区别好像很大,但自己说不出个所以然。还需继续努力!

——————————
连载3里面,第23和24条,在sed中用n表示奇数行,用p表示偶数行。
显示文本奇数行 sed -n -e "p" -e "n" a.txt
显示文本偶数行 sed -n -e "n" -e "p" a.txt

我在这里有个疑问,-e是sed中多个命令的连接。那为什么以上两条命令最终结果不是显示所有的行(包括奇、偶行)?


————
这样显示奇偶行,感觉更容易理解:
sed -n "1~2p" a.txt
sed -n "2~2p" a.txt
作者: taofan712    时间: 2017-3-6 15:46

回复 3# batman

再次阅读教程,有个关于感叹号的问题,希望能得到各位高手的解答。
感叹号!代表在除了某个条件,均执行某命令。
我看楼主两次前后两次使用百分号的位置不一样,自己没找到规律,也没测试出结果,望解答:
另,
1-a a-1 aa
2-a a-2 aa
3-a a-3 aa
4-a a-4 aa
5-a a-5 aa
(每行第一个和第三个a替换成b。能否用感叹号!做条件,类似:sed "s/a/b/!2" a.txt )
作者: 回家路上    时间: 2017-3-6 16:27

回复 30# taofan712


1、学的话一步一步学,先去学所以然,再来结合实例。不要仅仅执行实例看效果记实例。
2、有问题的话,不要在旧贴上一层一层盖楼,汇总一下过一段时间,【自己发帖】统一问,急得话群里问。
作者: mycmd    时间: 2017-8-28 00:48

我就想知道如何用 sed 替换一个 EXE文件中的十六进制代码,扒遍整个论坛,硬是找不到一篇有用的,sed -i "s/\x52\x61\x72\x21/\x52\x60\x72\x21/g" 1.exe 测试替换后的文件是坏的。
作者: yhcfsr    时间: 2018-8-31 15:29

回复 32# mycmd


    SED能读取EXE文件吗?
也许你可以试试ULTRAEDIT




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2