Sed简明教程
awk于1977年出生,今年36岁本命年,sed比awk大2-3岁,awk就像林妹妹,sed就是宝玉哥哥了。所以 林妹妹跳了个Topless,他的哥哥sed坐不住了,也一定要出来抖一抖。
sed全名叫stream editor,流编辑器,用程序的方式来编辑文本,相当的hacker啊。sed基本上就是玩正则模式匹配,所以,玩sed的人,正则表达式一般都比较强。
同样,本篇文章不会说sed的全部东西,你可以参看sed的手册,我这里主要还是想和大家竞争一下那些从手机指缝间或马桶里流走的时间,用这些时间来学习一些东西。当然,接下来的还是要靠大家自己双手。
用s命令替换
我使用下面的这段文本做演示:
1 2 3 4 5 6 7 8 9 </td> | $catpets.txt This is mycat mycat's name is betty This is my dog my dog's name is frank This is my fish my fish's name is george This is my goat my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed"s/my/Hao Chen's/g"pets.txt This is Hao Chen'scat Hao Chen's cat's name is betty This is Hao Chen's dog Hao Chen's dog's name is frank This is Hao Chen's fish Hao Chen's fish's name is george This is Hao Chen's goat Hao Chen's goat's name is adam | </tr> </tbody> </table> </div> </div>
1 </td> | $sed"s/my/Hao Chen's/g"pets.txt > hao_pets.txt | </tr> </tbody> </table> </div> </div>
1 </td> | $sed-i"s/my/Hao Chen's/g"pets.txt | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed's/^/#/g'pets.txt #This is my cat # my cat's name is betty #This is my dog # my dog's name is frank #This is my fish # my fish's name is george #This is my goat # my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed's/$/ --- /g'pets.txt This is mycat--- mycat's name is betty --- This is my dog --- my dog's name is frank --- This is my fish --- my fish's name is george --- This is my goat --- my goat's name is adam --- | </tr> </tbody> </table> </div> </div>
1 </td> | This is what | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 </td> | # 如果你这样搞的话,就会有问题 $sed's/<.*>//g'html.txt Understand? # 要解决上面的那个问题,就得像下面这样。 # 其中的'[^>]' 指定了除了>的字符重复0次或多次。 $sed's/<[^>]*>//g'html.txt This is what I meant. Understand? | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed"3s/my/your/g"pets.txt This is mycat mycat's name is betty This is your dog my dog's name is frank This is my fish my fish's name is george This is my goat my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed"3,6s/my/your/g"pets.txt This is mycat mycat's name is betty This is your dog your dog's name is frank This is your fish your fish's name is george This is my goat my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $catmy.txt This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $sed's/s/S/1'my.txt ThiS is mycat, mycat's name is betty ThiS is my dog, my dog's name is frank ThiS is my fish, my fish's name is george ThiS is my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $sed's/s/S/2'my.txt This iS mycat, mycat's name is betty This iS my dog, my dog's name is frank This iS my fish, my fish's name is george This iS my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $sed's/s/S/3g'my.txt This is mycat, mycat'S name iS betty This is my dog, my dog'S name iS frank This is my fiSh, my fiSh'S name iS george This is my goat, my goat'S name iS adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $sed'1,3s/my/your/g; 3,$s/This/That/g'my.txt This is yourcat, yourcat's name is betty This is your dog, your dog's name is frank That is your fish, your fish's name is george That is my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 </td> | sed-e'1,3s/my/your/g'-e'3,$s/This/That/g'my.txt | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $sed's/my/[&]/g'my.txt This is [my]cat, [my]cat's name is betty This is [my] dog, [my] dog's name is frank This is [my] fish, [my] fish's name is george This is [my] goat, [my] goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $sed's/This is my \([^,]*\),.*is \(.*\)/\1:\2/g'my.txt cat:betty dog:frank fish:george goat:adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed'N;s/my/your/'pets.txt This is yourcat mycat's name is betty This is your dog my dog's name is frank This is your fish my fish's name is george This is your goat my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 </td> | This is mycat\n mycat's name is betty This is my dog\n my dog's name is frank This is my fish\n my fish's name is george This is my goat\n my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 </td> | $sed'N;s/\n/,/'pets.txt This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 </td> | # 其中的1i表明,其要在第1行前插入一行(insert) $sed"1 i This is my monkey, my monkey's name is wukong"my.txt This is my monkey, my monkey's name is wukong This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam # 其中的1a表明,其要在最后一行后追加一行(append) $sed"$ a This is my monkey, my monkey's name is wukong"my.txt This is mycat, mycat's name is betty This is my monkey, my monkey's name is wukong This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 </td> | # 注意其中的/fish/a,这意思是匹配到/fish/后就追加一行 $sed"/fish/a This is my monkey, my monkey's name is wukong"my.txt This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my monkey, my monkey's name is wukong This is my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed"/my/a ----"my.txt This is mycat, mycat's name is betty ---- This is my dog, my dog's name is frank ---- This is my fish, my fish's name is george ---- This is my goat, my goat's name is adam ---- | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 </td> | $sed"2 c This is my monkey, my monkey's name is wukong"my.txt This is mycat, mycat's name is betty This is my monkey, my monkey's name is wukong This is my fish, my fish's name is george This is my goat, my goat's name is adam $sed"/fish/c This is my monkey, my monkey's name is wukong"my.txt This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my monkey, my monkey's name is wukong This is my goat, my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 </td> | $sed'/fish/d'my.txt This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my goat, my goat's name is adam $sed'2d'my.txt This is mycat, mycat's name is betty This is my fish, my fish's name is george This is my goat, my goat's name is adam $sed'2,$d'my.txt This is mycat, mycat's name is betty | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 </td> | # 匹配fish并输出,可以看到fish的那一行被打了两遍, # 这是因为sed处理时会把处理的信息输出 $sed'/fish/p'my.txt This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george This is my fish, my fish's name is george This is my goat, my goat's name is adam # 使用n参数就好了 $sed-n'/fish/p'my.txt This is my fish, my fish's name is george # 从一个模式到另一个模式 $sed-n'/dog/,/fish/p'my.txt This is my dog, my dog's name is frank This is my fish, my fish's name is george #从第一行打印到匹配fish成功的那一行 $sed-n'1,/fish/p'my.txt This is mycat, mycat's name is betty This is my dog, my dog's name is frank This is my fish, my fish's name is george | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 </td> | foreach line in file { //放入把行Pattern_Space Pattern_Space <= line; // 对每个pattern space执行sed命令 Pattern_Space <= EXEC(sed_cmd, Pattern_Space); // 如果没有指定 -n 则输出处理后的Pattern_Space if(sed option hasn't"-n") { print Pattern_Space } } | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 </td> | boolbexec =false foreach line in file { if( match(address1) ){ bexec =true; } if( bexec ==true) { EXEC(sed_cmd); } if( match (address2) ) { bexec =false; } } | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 </td> | # 其中的+3表示后面连续3行 $sed'/dog/,+3s/^/# /g'pets.txt This is mycat mycat's name is betty # This is my dog # my dog's name is frank # This is my fish # my fish's name is george This is my goat my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 </td> | $catpets.txt This is mycat mycat's name is betty This is my dog my dog's name is frank This is my fish my fish's name is george This is my goat my goat's name is adam # 对3行到第6行,执行命令/This/d $sed'3,6 {/This/d}'pets.txt This is mycat mycat's name is betty my dog's name is frank my fish's name is george This is my goat my goat's name is adam # 对3行到第6行,匹配/This/成功后,再匹配/fish/,成功后执行d命令 $sed'3,6 {/This/{/fish/d}}'pets.txt This is mycat mycat's name is betty This is my dog my dog's name is frank my fish's name is george This is my goat my goat's name is adam # 从第一行到最后一行,如果匹配到This,则删除之;如果前面有空格,则去除空格 $sed'1,${/This/d;s/^ *//g}'pets.txt mycat's name is betty my dog's name is frank my fish's name is george my goat's name is adam | </tr> </tbody> </table> </div> </div>
1 2 3 4 </td> | $catt.txt one two three | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 8 9 </td> | $sed'H;g't.txt one one two one two three | </tr> </tbody> </table> </div> </div>
1 2 3 4 </td> | $sed'1!G;h;$!d't.txt three two one | </tr> </tbody> </table> </div> </div>