sed处理文本方法

转载至http://lht821008.blog.163.com/blog/static/416478620110411959705/
#删除每一行开头的空白 (空格,TAB)左对齐排列全文.
sed 's/^[ \t]*//'
### 替换成空,^[ \t]* 的含义为以空格或者TAB键开始的(或者是他们的组合)行.

#从每一行结尾处删除最后的空格(空格,TAB)
sed 's/[ \t]*$//'

#删除每一行的开头和结尾的空格
sed 's/^[ \t]*//;s/[ \t]*$//'

#在每一行开始处插入5个空格(整页偏移)
sed 's/^/ /'

#右对齐,按79列宽排列所有文本
sed -e :a -e 's/^.\{1,78\}$/ &/;ta' 
###这个语句好像很麻烦,不过看懂了还挺有意思.:)
###首先出现了几个新东东1.":"  2."&". 3. "-e " 4."t",解释一下
###1.":"  Label for b and t commands.(给b和t命令加注标签)
###2."&" 表示重复整个匹配的规则表达式.
###3. "-e" add the script to the commands to be executed
###   把脚本加到命令里用以执行  
###如果从读入最后一个输入行并且执行最后一个t或者T命令后,一个s///命令成功替换,
###那么流程分支指向label处,如果label被忽略(就是没有成功替换吧,我想),那么流程
###分支指向脚本结束.
###回过头来看,整个sed命令行是一个循环执行的语句,每一行都要替换(78-当前行的字
###符数)次,所以如果整个文件比较大,或者一行字符数比较少,做这个动作就有点吃力了.
###不信你试试吧,呵呵.

#使所有文本居于79列宽的格式中央。在第一种方法中,每一行开头处的空格是
#很重要的,最后的空格被附在行尾。第二种方法中,一行开头的空格在中心对
#齐的行中被丢弃,行尾也没有原来结尾处的空格。
sed -e :a -e 's/^.\{1,77\}$/ & /;ta' # method 1
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\(*\)1/\1/' # method 2


#在每一行中用"bar" 替换(找并替换)foo"
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
                  #在一行中替换所有出现的值
###就不直接翻译了,大概意思就是replacement处可以包含&代表匹配的模式空间中
###的部分,特殊的\1-\9可以代表regexp中相应的"子表达式",也就是说前面regexp
###可以分为几个子表达式,而后边 replacement中可以用\1-\9分别代表它们.这样就
###增加了灵活性,便于修改sed命令.
###把regexp中的\去掉后,就变成(.*)foo(*foo),其中(.*)表示零个或者多个字符,
###这样加上后边的\1bar\2就变成了改变倒数第二个foo,而倒数第一个不变

sed 's/\(*\)foo/\1bar/' #只替换最后一个值

#在每一含有"baz"的行中用"bar"替换(查找并替换)foo"
sed '/baz/s/foo/bar/g'
### /baz/用来查找,后边的用来替换

#在每一不含有"baz" 的行中用"bar"替换(找并替换)foo"
sed '/baz/!s/foo/bar/g'

#将"scarlet"或者"ruby"或者"puce"替换成"red"
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' # most seds

#反转文章行的顺序(类似"tac" )
sed '1!G;h;$!d' # method 1
sed -n '1!G;h;$p' # method 2

#反转一行中每个字符的顺序(类似"rev")
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//' 
###'/\n/!G'是判断本行是否有换行符,如果没有执行G命令
###'s/\(.\)\(.*\n\)/&\2\1/'命令是在原来行+第二个字符(或者没有)开始到换行符+第一个字符
###//D命令是在模式空间删除第一行,注意执行完成后如果模式空间不为空,继续下一个
###循环执行.
###s/.//命令是删除第一个字符

#把两行合为一行(类似于"paste")
sed '$!N;s/\n/ /'

#如果一行以"\"结束,把下一行加在此行上
sed -e :a -e '/\\$/N; s/\\\n//; ta'

#如果一等号开始某一行,把这一行加到前一行后边,并且用一个空格替换等号
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
## P命令--Print up to the first embedded newline of  the  current 
###pattern  space.打印当前模式空间中第一行。
###D命令--Delete up to the first embedded newline in
### the  pattern  space. Start  next  cycle,  but skip reading from
###the input if there is still data in the pattern space.
###删除当前模式空间中第一行。开始新的循环,但是如果在模式空间中仍然
###有数据,那么跳过读取输入。

#给数字串加逗号,把"1234567"变为"1,234,567"
gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta' # GNU sed
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'  # other seds
###(.*[0-9])表示零个或者多个字符(可能包含数字)+一个数字,而
###([0-9]{3})表示三个数字, 然后不停的替换,直到条件不成立,也就是没有
###四个以上连续的数字出现就停止了.

#给带有小数点和负号的数字的数字加上逗号
gsed ':a;s/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g;ta'

#每五行后加一空行
gsed '0~5G' # GNU sed only
sed 'n;n;n;n;G;' # other seds

#打印一个文件的前10行(模仿动作"head")
sed 10q

#打印一个文件的第一行(仿"head -1")
sed q
### q命令的解释Immediately quit the sed  script  without  processing
###any  more input,  except  that  if  auto-print is not disabled the
###current pattern space will be printed.
### 所以上边两个命令都清楚了,执行到第10行退出就打印前10行,执行第一行
###就退出就打印第一行  

#打印一个文件的后10行(仿"tail")
sed -e :a -e '$q;N;11,$D;ba'
###Label b : Branch to label; if label is omitted, branch to end of script.
###命令D 删除模式空间内第一个 newline 字母 \n 前的资料。 
###命令N 把输入的下一行添加到模式空间中。
### b label:分支到脚本中带有标号的地方,如果标号不存就分支到脚本的末尾

#打印一个文件的最后两行(仿"tail -2")
sed '$!N;$!D'
###sed '$!N;$!D' : 对文件倒数第二行以前的行来说,N 将当前行的下一行放到模
###式空间中以后,D 就将模式空间的内容删除了;到倒数第二行的时候,将最后一行
###附加到倒数第二行下面,然后最后一行不执行 D ,所以文件的最后两行都保存下来了。
###不知道是这段话说得有些含糊,还是我理解得有偏差,总觉得D命令解释成
###"将模式空间的内容删除了"有些让人糊涂.
###而我是这样理解的,不知道对不对.首先说D命令是 Delete up to the first
###embedded newline in  the  pattern  space.也就是说D命令是删除模式空间中
###第一个换行符之前的内容,也就是删除第一行.然后D命令的解释还有一句,我认为
###这句很重要: Start  next  cycle,  but skip reading from the input if there
### is still data in the pattern space.开始下一个循环,但是如果模式空间中有 
###数据,则跳过从输入中读取数据.

#打印一个文件的最后一行(仿"tail -1")
sed '$!d' # method 1
sed -n '$p' # method 2

#只打印匹配的一定字符的行(仿"grep")
sed -n '/regexp/p' # method 1
sed '/regexp/!d' # method 2

#只打印于一定字符不匹配的行(效"grep -v")
sed -n '/regexp/!p' # method 1, corresponds to above
sed '/regexp/d' # method 2, simpler syntax

#打印包含"regexp"那一行的上一行,但是不打印包含"regexp"的行.
sed -n '/regexp/{g;1!p;};h'
###在命令执行到包含"regexp"那一行的上一行时,模式空间中这行的内容被
###拷贝到保留空间中.执行到包含"regexp"那一行时就打印它了.

#打印在"regexp"之后紧跟那一行,但是除去包含"regexp"的行.
sed -n '/regexp/{n;p;}'

#在"regexp"前后打印一行上下文,使其行号指示"regexp"在哪里出现(
#grep -A1 -B1相似)
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h

#查找"AAA"和"BBB"和"CCC".(任意顺序)
sed '/AAA/!d; /BBB/!d; /CCC/!d'

# 查找"AAA"和"BBB"和"CCC".(一定顺序)
sed '/AAA.*BBB.*CCC/!d'

#查找"AAA"或"BBB"或"CCC".(任意顺序)
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # most seds
gsed '/AAA\|BBB\|CCC/!d' # GNU sed only

#如果某段包含"AAA",则打印这一段。(空行用来分隔段落)
#HHsed v1.5必须在'x;'之后插入一个'G;'
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'

#如果某段包含"AAA"和"BBB"和"CCC",则打印这一段
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'

# 如果某段包含"AAA"或"BBB"或"CCC",则打印这一段
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d' # GNU sed only

#仅打印长于65个字符的行
sed -n '/^.\{65\}/p'

#仅打印少于65个字符的行
sed -n '/^.\{65\}/!p' # method 1, corresponds to above
sed '/^.\{65\}/d' # method 2, simpler syntax

#打印从字符"regexp"开始到文件结束的部分
sed -n '/regexp/,$p'
###还没啥,注意","的作用是选择行的范围,从包含regexp的行到最后一行

#根据行号来打印文件的一部分(-12行,包括在内)
sed -n '8,12p' # method 1
sed '8,12!d' # method 2

#打印第52行
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3, efficient on large files
###仅注意第三种方法效率比较高就行了

#从第三行开始,每7行打印一行
gsed -n '3~7p' # GNU sed only
sed -n '3,${p;n;n;n;n;n;n;}' # other seds

#打印文件中指定字符之间的部分(含字符在内)
sed -n '/Iowa/,/Montana/p' # case sensitive

#打印除指定字符之间部分之外的全文
sed '/Iowa/,/Montana/d'

#删除文件中重复的连续的行(似于"uniq"命令)
#重复行中第一行保留,其他删除
sed '$!N; /^\(.*\)\n\1$/!P; D'  
###如果不是最后一行,就把下一行附加在模式空间,然后进行查找操作
###"^"和"$"中间的内容如果有重复就匹配成功.如果匹配不成功就用P打印
###第一行. 然后删除第一行.

#删除文件中重复的,但不连续的行。注意不要溢出保留空间的缓冲器的大小,
#否则使用GNU sed.
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'  

#删除一个文件中前10行
sed '1,10d'

#删除一个文件中最后1行
sed '$d'
###与上边一个都是查找删除

#删除一个文件中最后2行
sed 'N;$!P;$!D;$d'

#删除一个文件中后10行
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2

# 每8行删除1行
gsed '0~8d' # GNU sed only
sed 'n;n;n;n;n;n;n;d;' # other seds

#删除文件所有空白行(似于"grep '.' ")
sed '/^$/d' # method 1
sed '/./!d' # method 2

#删除文件中除一行空白行之外的所有连续空白行,也同时删除所有从头到尾的所
#有空白行(似于"cat -s")
sed '/./,/^$/!d' # method 1, allows 0 blanks at top, 1 at EOF
                 #方法1不允许文件顶部有空行,文件尾部可以
sed '/^$/N;/\n$/D' # method 2, allows 1 blank at top, 0 at EOF
                 #方法2不允许文件尾部有空行,文件顶部可以
###两个先选择,后删除命令.不多说了.

#删除文件中连续空行中除前两行空白行之外的所有空白行
sed '/^$/N;/\n$/N;//D'
###跟上边的命令相似,多了一步而已.               

#删除文件开头部分中的所有空白行
sed '/./,$!d'
###从有字符开始的行直到最后一行保留,其他删除.

#删除文件结尾部分中的所有空白行
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' # works on all seds
sed -e :a -e '/^\n*$/N;/\n$/ba' # ditto, except for gsed 3.02*

#删除每个段落中最后1行
sed -n '/^$/{p;h;};/./{x;/./p;}'

# 从man page页里删除所有overstrikes(字符,backspace).如果使用unix系统v
#或者bash shell,echo命令可能需要-e参数.
sed "s/.`echo \\\b`//g" # double quotes required for Unix environment
                        #unix环境下需要双引号
sed 's/.^H//g' # in bash/tcsh, press Ctrl-V and then Ctrl-H
               #在bash/tcsh中,按Ctrl-V然后按Ctrl-H
sed 's/.\x08//g' # hex expression for sed v1.5
                 #sed v1.5中的hex表达式

# 获得新闻组/e-mail信息的标题部分
sed '/^$/q' # deletes everything after first blank line

#获得新闻组/e-mail信息的主体部分
sed '1,/^$/d' # deletes everything up to first blank line

#获得题目的标题,但是删去开始的"Subject: "部分
sed '/^Subject: */!d; s///;q'

#获得返回的地址标题()
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'

#正确解析地址。把email地址从一行中单独提出来并返回地址头()
sed 's/ *(*)/; s/>.*//; s/.*[:<] *//'

#给每行增加的尖括号和空格()信息被引用)
#sed 's/^/> /'

#删除每行的尖括号和空格()信息不被引用)
sed 's/^> //'

#删去大部分HTML标签(供多行标签))
sed -e :a -e 's/<[^>]*>//g;/</N;//ba'

#抽取多部分未编码的二进制字节,删除无关的头信息,使得只保留未编码的部分.
#文件传送给sed必须保持正确的顺序。第一版本可以用于命令行的执行,第二版本
#可以制作成一个可执行的unix shell脚本
sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode # vers. 1
sed '/^end/,/^begin/d' "$@" | uudecode # vers. 2

#独立的压缩每个txt文件,删除原文件并且根绝原文本文件设置每个zip文件名。
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^\(*\).TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat

猜你喜欢

转载自luocb1980.iteye.com/blog/1066427