linux shell笔记之sed

      这篇记录一下sed的基本用法,建议看下sed与awk第三版里面介绍的很详细,sed通过正则表达式匹配出命令处理文本,如果对正则不熟悉是件很头疼的事。注意以下脚本都是在脚本文件上测试的使用命令sed -f scrift files

      1.sed先读取一行至模式空间,取前先清除以前模式空间内容(多行模式下读取命令N除外),脚本从脚本顶部开始处理模式空间的内容,处理一条命令更新模式空间内容,新的命令在更新后的模式空间上进行,到达脚本底部后默认送往屏幕显示也可以使用-n禁止这个默认输出,sed 对源文件内容不做修改。

      2.sed命令可以指定0个1个或2个地址,每个地址是一个描述模式,行号或行寻址符号的正则表达式。

      3.sed命令 格式sed [options] 'command' files;  sed [options] -f scriptfile files

              3.1   追加,插入,更改

      a\     在当前行后面加入一行文本。
      i\      在当前行上面插入数据,新插入的数据不会被读入处理。
      c\     改变行的文本,如1~3行变成123456789
              1,3c\123456789

              $a\end of file  在最后一行后加入
              $i\end of file  在最后一行前加入
              $c\end of file  替换掉最后一行
      这里碰到奇怪的问题,sed与awk第三版说aic会修改模式空间的内容,自带帮助文件没提及,测试发现aic命令执行后后面的命令没被执行,如
      1{
         c\1234
         =
         =
         p
         p
         p
      }
      更改第一行内容为1234,后面打印行号和测试的输出,但结果后面的命令不执行了,如果知道请告知一下谢谢。

           

           3.2  替换  [address]s/pattern/replacement/flags   用replacement替换正则表达式pattern。flag可以是一下标示。

 
     n  1~512之间的数字,表示只替换第n次出现的pattern
     g  全部替换,没有g只替换第一次出现的pattern
     p  只是打印
     W  file  写入文件
     如果没有匹配地址那么匹配全部行,和地址不同地址的定界符为斜杠/,正则表达式可以使用任意字符分割如s/444/111/,可以写成 s244421112,现在分割
符号是2,当然这是例子最好不要这样写。如果表达式内包含定界符那么需要用反斜杠来转义它。

     在pattern部分我们可以用\(和\)来分块,在替换部分repalcement可以使用\n(n是数字)来表示pattern的第几块,使用&表示整个pattern匹配出来的字符
串,
   例子如文档中多处出现google里面的o是不定的,但发现少写了个e。可以 s/\/&e/g,\<和\>是锚定单词,&e表示只在原来基础上加个e。
   例子如google内o不定发现少了个g,替换时要保留原来o的个数怎么办呢?这就需要用块了,s/\/g\1gle/g,这里pattern内用\(和\)分了
块,然后在replacement内调用块内的内容\1。


 3.3 删除行d,如删除1,3行 1,3d

 3.4 列表l   列出不能打印字符的清单,将不能打印的字符显示为两个数字显示的ascii代码,如\n \t...

 3.5 转换  [address]y/abc/xyz/

      这个命令按位置将字符串abc中的每个字符转换为xyz中对应的字符。   
      如转换大小写可以y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

 3.6 打印  p

 3.7 打印行号 =

              3.8 读入下一行 n 用下一命令处理,而不是重新处理,如下找到行111的行处理后,下一行如果是空行那么删除下一行

    /111/{
            s/111/222/;
            n;
            /^$/d;
         }
    实际上,next命令导致输入的下一行取代模式空间的当前行,脚本的后续命令作用于替换后的行。



           3.9 读写文件

   r file   读入文件不存在也不会报错
   w file   写入文件如果不存在将创建一个,如果存在那么首次写入清空旧数据,以后写入为追加写入。

          3.10 退出 q   退出sed         

  如匹配到111的行后退出 sed /111/q file


         3.11 ! 表示后面的命令对所有没有被选定的行发生作用。
         3.12 = 打印当前行                   
         3.13 # 注释行



高级命令,sed通常读一行至模式空间,并逐条执行脚本中的命令,脚本结束时输出这一行并清空模式空间,然后读下一行至模式空间如此循环,sed的多行模式命令可以一次读入多行然后进行匹配处理,如处理跨行的词组。


           3.14 多行模式空间 N D P  对应单行模式下的n d p

   
    P只打印多行模式的第一行,p打印整个模式控件内容。P经常出现在N之后和D之前。

    D只删除多行模式的第一行,不读新入行至模式空间,但会回到脚本顶端,重执行脚本,d 删除模式空间的内容,导致读入新行并重新执行脚本

    N读取新的行并添加只模式空间现有内容后,读入的行自动用换行\n分割开来。读入多行模式空间内的所有行可以看成是带有换行\n的单行数据,^匹配第一
行的开头$匹配最后一行的结尾。例如替换跨行的词组hello sed
,替换成单行。 
ex1:替换相邻行
   hello
    sed
   替换成一行 hello sed

    /hello$/{
       N;
       s/hello\nsed/hello sed/
    }
    
ex2: 将多个空白行替换成一个空白行
/^ *$/{
   N;
   /^ *\n$/D;
}
    如果把D改成小写d,那么当空白行为偶数时全部空白被删除,奇数时保留1行,因为模式空间凑够两行后d命令删除空间内的全部并取下一行,使用D先匹配到
一行空白行,取下一条如果是连续空白行那么删除第一行后,会回到脚本顶端,重新按当前模式空间的内容执行脚本。

           3.15 采用保持空间来保存模式空间内容,使用H h G g x操作保持空间的内容

    模式空间是当前处理的缓冲区,还有个个保持空间,类似剪切板,可以将处理的内容复制到保持空间,

    hold  h/H  将模式空间的内容复制/追加至保持空间
    get   g/G  将保持空间的内容赋值/追加至模式空间
    x          模式空间和保持空间的内容互换

    h    拷贝选中内容到保持空间,以前缓存的内容被清掉。
    H    追加选中内容到保持空间,以前缓存的内容不变,这样可以缓存多行。
    g    获取保持空间内容,并 替换 模式空间中的内容。
    G    获取保持空间内容,并 追加 模式空间的 后面。

       3.16 使用分支和条件指令 : b t T

 分支(b)和测试(T/t)命令脚本中的控制转移到包含特殊标签的行。如果没有标签那么转移到脚本结尾处。
    
    分支b用于无条件转移  [address] b [label] label可选,当无label时跳至脚本结尾。
    测试t用于条件转移    [address] t [label] label可选,当无label时跳至脚本结尾。如果当前匹配地址的行上进行了成功的替换,那么test命令会转到标
                         签处
    测试(T)和(t)相反 用于条件转移   [address] t [label] label可选,如果当前匹配地址的行上进行了替换失败,那么test命令会转到标签处
    
    T 和 t测试的是s///替换命令的结果

    标签本身占有一行使用:开头,使用b label无条件跳转,

使用分支b跳转方式删除多行空白,替换成一行空白,当读到空白行时循环读出,然后将多行模式空间的空白行替换成单一空白行
/^ *$/{
:rdn
   N;
   /^\( *\n*\)\{1,\}$/b rdn;
  s/^\( *\n*\)\{1,\}\n/\n/
}

使用测试t跳转方式删除多行空白,替换成一行空白,当读到空白行时,读下一行然后替换两空白行为一空白行,如替换成功接着读下一行,直到替换失败
/^ *$/{
:loop
  N;
  s/^\( *\n*\)\{1,\}$//;
  t loop
}

 


         4.[options]

     4.1 -e command, --expression=command    允许多台编辑。
     4.2 -h, --help         打印帮助,并显示bug列表的地址。
     4.3 -n, --quiet, --silent  取消默认输出。
     4.4 -f, --filer=script-file  引导sed脚本文件名。
     4.5 -V, --version    打印版本和版权信息。



        5.元字符集

     ^  锚定行的开始  如匹配1111开头的行,/^1111/
     $  锚定行的结束  如匹配aaaa结尾的行,/aaaa$/
     .  匹配一个字符 包括换行符号
     *  匹配零或多个字符
     [] 匹配 一个 指定范围的字符 如[123]k匹配1k 2k 3k
     [^]匹配一个不在指定范围内的字符
     \(..\)  保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
     &  保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
     \< 锚定单词的开始,如:/\ 锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。
     x\{m\}  重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。
     x\{m,\} 重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。
     x\{m,n\}重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。
     \+ 至少一个匹配
     \? 0个或1个
     \| `REGEXP1\|REGEXP2'  Matches either REGEXP1 or REGEXP2. 如删除包含111或222的行/111\|222/d





        6.嵌套分组命令

    sed使用大括号将一个地址嵌套在另一个地址中,或相同地址应用多个命令,例如匹配3~8行内匹配包含444的地址sed脚本文件可以如下
3,8{
  /444/{
    s/444/333/
    其他指令
  }
}
   上面例子s/444/333/前又可以加匹配地址,每个命令可以有自己的地址并允许多层嵌套,如果命令之间有个分号,那么可以多个sed命令放同一行,有些命令
会把;当输出数据了,如a,未阅读方便不提倡写在同一行。一些sed说明注释智能在第一行出现,命令内不能有多余空格,大括号后不能有空格,右大括号要单
独一行的约束,但是再我使用的sed版本GNU sed 版本 4.2.1并没有这些限制。













你可能感兴趣的:(Linux)