一. sed
sed(Stream Editor)译为流式编辑器,既然是一款编辑器,那么其主要作用就是对文本内容进行相应的编辑处理,它可以通过事先指定的模式对一个或多个文件进行自动化处理,从而简化对文件的反复操作;
sed使用的基本格式为:
命令行:sed [选项]... '编辑命令' [文件]...
脚本:sed [选项]... -f [编辑脚本文件] [文件]...
其中,编辑命令的格式为:/PATTERN/ACTION;
PATTERN是正则表达式,ACTION是相应的操作,也就是将满足正则表达式的行进行相应的ACTION,如果省略了PATTERN,则表示对文件中所有的行都进行ACTION操作;
二. 保持空间与模式空间
sed的处理模式是行处理,在处理时,sed首先会先拿到文件内容的一行,然后放到一个缓冲区中进行处理,这个缓冲区被称为“模式空间”,处理完毕后将处理结果输出到标准输出上,然后缓冲区为空再接着拿取下一行到模式空间进行处理,直到文件结尾;整个过程并不会影响文件的原内容,除非将结果进行重定向回原文件;
对于sed来说,其处理文件内容的缓冲区被称为模式空间(pattern space),同时,sed还拥有另外一种缓冲区被称为保持空间(hold space);保持空间可以被看做是sed的后备存储仓库,也就是暂存需要处理的内容;而模式空间才是真正的工作区,一般情况下是不会使用到保持空间的,只使用模式空间来一行一行的处理就可以了,但有时候模式空间要完成的任务需要保持空间来辅助,这就需要用到几条高级命令:
+g:将保持空间的内容拷贝到模式空间,则模式空间原来的内容会被清空;
+G:将保持空间的内容追加到模式空间;
+h:将模式空间的内容拷贝到保持空间,则保持空间原来的内容会被清除;
+H:将模式空间的内容追加到保持空间;
+n:读入下一行内容,将其拷贝到模式空间;
+N:读入下一行内容,将其追加到模式空间;
+d:删除模式空间的所有内容,并读入下一行到模式空间;
+D:仅删除模式空间的第一行,不读入下一行;
+x:交换模式空间和保持空间的内容;
简单来记,g就是get,从保持空间get内容到模式空间;h就是hold,从模式空间hold内容到保持空间;n表示next,读入下一行;d表示delete,删除模式空间的内容;小写都是拷贝,大写都是追加;
三. 栗子时间
这里要解释为什么单单用一个G就可以了,首先G是将保持空间的内容追加到模式空间;而保持空间的内容刚开始第一行就是一个空行,因此,只需要每次从file中读取一行的时候都将保持空间的空行追加到模式空间也就是从file中读取的一行后面就可以了;但这里并不影响file文件的内容,如果想要改变,只需要加上-i选项就可以了,表示处理的结果会影响原文件;
2. 用sed模拟tac功能
cat是输出文件的内容,而tac和其字面字词一样是cat的逆序,也就是会逆序输出文件的内容;
因为模式空间是一行一行的处理文件内容,想要逆序输出就要借助保持空间,首先如果是第一行就不执行G而是将模式空间读取到的第一行内容拷贝到保持空间也就是'hello 1',然后删除模式空间的所有内容并读入下一行,这时候再去处理不是第一行的内容'hello 2',就将保持空间的内容追加到模式空间,此时模式空间为'hello 2 \n hello 1'然后再一起拷贝回去,如此反复,直到最后一行的时候不再删除,处理完毕;
3. 追加匹配行到文件结尾
将满足匹配条件的内容行追加到文件的结尾处;
将满足条件的内容追加到保持空间,当处理到最后一行的时候将保持空间的内容追加到模式空间,这里有一个空行前面说过保持空间本身就会有一个空行;
4. 行列转化
将文件中的行排列转换为列排列;
因为如果要转换则模式空间中至少要有一行以上的数据,因此可以每读入一行数据到模式空间的时候都将其追加到保持空间,当处理到最后一行的时候将模式空间与保持空间的内容交换,这时候模式空间里面就是file的内容,然后再进行整体的将‘\n’替换成空格;
5. 1~100求和
seq表示列出从1到指定数字的序列,之后将序列交给sed,首先将每一行都追加到保持空间内,如果是最后一行则交换保持空间和模式空间的内容,这时候再对交换后模式空间的内容进行处理,将所有的‘\n’都替换为‘+’,之后再交给bc计算工具处理就可以了;
另外一种求1~100的和:
:a可以看做是一个标签,N表示不断地读入并且将其追加到模式空间内,ba表示跳到标签处,也就是如果不是最后一行就不断地读读读直到最后一行也被追加进来的时候,模式空间的内容就是序列的内容,此时再进行整体的将‘\n’替换成‘+’,同样的,将其交给bc计算出和;
6. 打印奇数行和偶数行
对于N来说是读入下一行追加到模式空间,而n则是读入下一行并且拷贝到模式空间,这里拷贝就会将模式空间原来的值覆盖掉,因此,先进行n再进行p操作打印出的就是偶数行,而先进行p操作再进行读入拷贝打印出的就是奇数行;
《完》
|