http://blog.chinaunix.net/uid-26805356-id-4088668.html
http://www.cnblogs.com/edwardlost/archive/2010/09/17/1829145.html
sed是非交互式的编辑器。它不会修改文件,除非使用shell重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。 sed编辑器逐行处理文件(或输入),并将结果发送到屏幕。具体过程如下:首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed便结束运行。sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改原文件。
定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed将处理输入文件的所有行。
地址是一个数字,则表示行号;是“$”符号,则表示最后一行。例如:
sed -n '3p' datafile
只打印第三行
只显示指定行范围的文件内容,例如:
# 只查看文件的第100行到第200行
sed -n '100,200p' mysql_slow_query.log
地址是逗号分隔的,那么需要处理的地址是这两行之间的范围(包括这两行在内)。范围可以用数字、正则表达式、或二者的组合表示。例如:
sed '2,5d' datafile
#删除第二到第五行
sed '/My/,/You/d' datafile
#删除包含"My"的行到包含"You"的行之间的行
sed '/My/,10d' datafile
#删除包含"My"的行到第十行的内容
sed命令告诉sed如何处理由地址指定的各输入行,如果没有指定地址则处理所有的输入行
sed不向grep一样,不管是否找到指定的模式,它的退出状态都是0。只有当命令存在语法错误时,sed的退出状态才不是0。
a\ 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行
c\ 用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行
i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行
d 删除行
h 把模式空间里的内容复制到暂存缓冲区
H 把模式空间里的内容追加到暂存缓冲区
g 把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容
G 把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面
l 列出非打印字符
p 打印行
n 读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理
q 结束或退出sed
r 从文件中读取输入行
! 对所选行以外的所有行应用命令
s 用一个字符串替换另一个
g 在行内进行全局替换
w 将所选的行写入文件
x 交换暂存缓冲区与模式空间的内容
y 将字符替换为另一字符(不能对正则表达式使用y命令)
-e 进行多项编辑,即对输入行应用多条sed命令时使用
-n 取消默认的输出
-f 指定sed脚本的文件名
与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线”/”之间的模式。 如果要把正则表达式分隔符”/”改为另一个字符,比如o,只要在这个字符前加一个反斜线,在字符后跟上正则表达式,再跟上这个字符即可。例如:sed -n ‘\o^Myop’ datafile
元字符 | 功能和示例
-----------------------------
^ | 行首定位符 /^my/ 匹配所有以my开头的行
$ | 行尾定位符 /my$/ 匹配所有以my结尾的行
. | 匹配除换行符以外的单个字符 /m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行
* | 匹配零个或多个前导字符 /my*/ 匹配包含字母m,后跟零个或多个y字母的行
[] | 匹配指定字符组内的任一字符 /[Mm]y/ 匹配包含My或my的行
[^] | 匹配不在指定字符组内的任一字符 /[^Mm]y/ 匹配包含y,但y之前的那个字符不是M或m的行
\(..\) | 保存已匹配的字符 1,20s/\(you\)self/\1r/ 标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。
| 最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。
& | 保存查找串以便在替换串中引用 s/my/**&**/ 符号&代表查找串。my将被替换为**my**
\< | 词首定位符 /\<my/ 匹配包含以my开头的单词的行
\> | 词尾定位符 /my\>/ 匹配包含以my结尾的单词的行
x\{m\} | 连续m个x /9\{5\}/ 匹配包含连续5个9的行
x\{m,\} | 至少m个x /9\{5,\}/ 匹配包含至少连续5个9的行
x\{m,n\} | 至少m个,但不超过n个x /9\{5,7\}/ 匹配包含连续5到7个9的行
程序1:shell的某一行的某一列
#!/bin/bash
Fname=$1
Lines=`cat $Fname |wc -l`
for ((N=1;N<=$Lines;N++));
do
Var1=`sed -n "${N}p" $Fname`# 获得某一行
Var2=`echo $Var1 |awk '{print $1}'`
echo -e "当前处理的是第${N}行,\t内容是:$Var1,\t它的第一列值是$Var2"
done;
程序2:获得没有使用的磁盘
# acquire a disk
ls /dev/sd* | awk '$1 !~/sda/' > tmp
for nodisk in `df -lh | awk '$1 ~/sd/ {print $1;}'`;
do
awk '$1 !~/'${nodisk:5:3}'/' tmp > disks #字符串第5个字符开始的3个字符
done
TargetVolume=`sed -n "1p" disks`
程序3:打印多个,并查找字符串
awk '{print $3, $4}' hhb.txt > output.txt
sed -n '/hhb/'p > output.txt
程序4:如何修改文件
sed -i "s/BDF_TYPE=2/\BDF_TYPE=\"NIC\"/g" nic/m_ass/ts4_vf.sh
程序5:在某一行后面增
1 #!/bin/sh
2
3 files= nic/pcie/ts2.sh nic/pci_nomsi/ts1_s3.sh nic/pci_nomsi/ts1.sh nic/pci_nomsi/ts2_s3.sh \
4 nic/pci_nomsi/ts2.sh nic/m_ass_nomsi/ts1.sh nic/m_ass_nomsi/ts2.sh nic/m_ass/ts1.sh nic/m_ass/ts2.sh nic/hotplug/pci_32.sh \
5 nic/hotplug/pci_64.sh nic/hotplug/pcie_32.sh nic/hotplug/pcie_64.sh nic/pcie_nomsi/ts1_s3.sh nic/pcie_nomsi/ts1.sh \
6 nic/pcie_nomsi/ts2_s3.sh nic/pcie_nomsi/ts2.sh nic/hotplug_nomsi/pci_32.sh nic/hotplug_nomsi/pci_64.sh nic/hotplug_nomsi/pcie_32.sh \
7 nic/hotplug_nomsi/pcie_64.sh nic/pci/ts1_s3.sh nic/pci/ts1.sh nic/pci/ts2_s3.sh nic/pci/ts2.sh
8
9 for file in nic/pcie/ts2.sh nic/pci_nomsi/ts1_s3.sh nic/pci_nomsi/ts1.sh nic/pci_nomsi/ts2_s3.sh
10 do
11 sed -i "s/BDF_TYPE=1/BDF_TYPE=\"NIC\"/g" $file
12 sed -i "/BDF_TYPE/a\BDF_SUB_TYPE=\"NIC\"" $file
13 done
程序6:逐行读入文本-变量去除换行^M,\r,\n
cat keywords.txt |while read line
do
line=${line//[$'\t\r\n']}
cdomain=$line.$domain
done
程序7:SSH字符串处理
#!/bin/sh
set -x
. ./lib/VMMCommon.sh
hhb=`VMM_SSH ivt-ex2 "rdmsr 0x179" | grep password -A1 | sed -n 2p | awk '{print $1}'`
#hhd=${hhb//[$'\t\r\n']}
echo $((16#${hhb//[$'\t\r\n']})) $((16#8000000)) | awk '{print and($1, $2)}'
程序8: 替换某个变量的值
sed -i "s%^address.*$%address $virtual_ctrl_IP%g" $BASE_DIR/config/interfaces_ctrl
sed -i "s%^netmask.*$%netmask $virtual_ctrl_netmask%g" $BASE_DIR/config/interfaces_ctrl
sed -i "s%^gateway.*$%gateway $virtual_ctrl_gateway%g" $BASE_DIR/config/interfaces_ctrl
程序9 去除头部两个字符(一个字符一个点,头部 '^'),尾部('$')三个字符
echo 0x12343000 | sed 's/^.x//g' | sed 's/...$//g'
获取字符串第n个位置到m个位置
$ echo $gpa | cut -b3-7
$ export str="0x123000"
$ echo ${str:3:3} // ${str:begin:len}
230
按指定的字符串截取
${varible##*string} 从左向右截取最后一个string后的字符串
${varible#*string}从左向右截取第一个string后的字符串
${varible%%string*}从右向左截取最后一个string后的字符串
${varible%string*}从右向左截取第一个string后的字符串
“*”只是一个通配符可以不要
例子:
$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg
截取字符变量的前8位,有方法如下:
1.expr substr “$a” 1 8
2.echo $a|awk ‘{print substr(,1,8)}’
3.echo $a|cut -c1-8
4.echo $
5.expr $a : ‘\(.\\).*’
6.echo $a|dd bs=1 count=8 2>/dev/null