sed

sed   '/yaoshuyin/d'    tmp.txt                                      #删除含yaoshuyin行
sed   'g/yaoshuyin/d'  tmp.txt                                      #删除所有含yaoshuyin的行

sed  's/yao/xxxx/'       tmp.txt                                      #把所有的yao替换成xxxx
sed  's/yao/xxxx/g'     tmp.txt                                      #把所有的yao替换成xxxx
sed  '/8092/s/httpd/xxxxx/g'   tmp.txt                          #把所有含8092行中的httpd换成xxxxx
  
===========================================================
每行几个操作的组合
sed  's/yao/xxxx/g;s/tom/xxxy/g'  tmp.txt  或 sed  -e 's/yao/xxx/g'  -e  's/tom/xxxy/'   tmp.txt


============================================================
脚本文件
-----------------------------
#cat xxx.sed
s/tom/yoa/
s/yoa/tnm/
-----------------------------
sed  -f  xxx.sed  tmp.txt


============================================================
仅输出修改后的行
[cnscn@cnscn /home/cnscn]$ sed -n -e  /8092/s/httpd/xxxxx/gp tmp.txt  (如果不输出的话就去掉p)
apache    1819  0.0  6.4 19808 8092 ?        S    08:45   0:00 [xxxxx]
apache    1820  0.0  6.4 19808 8092 ?        S    08:45   0:00 [xxxxx]


============================================================
同时使用awk和sed
apache    1819  0.0  6.4 19808 8092 ?        S    08:45   0:00 [xxxxx]
apache    1820  0.0  6.4 19808 8092 ?        S    08:45   0:00 [xxxxx]
apache    1821  0.0  6.4 19808 8092 ?        S    08:45   0:00 [xxxxx]
apache    1823  0.0  6.4 19808 8092 ?        S    08:45   0:00 [xxxxx]
apache    1825  0.0  6.4 19808 8092 ?        S    08:45   0:00 [xxxxx]
apache    2090  0.0  6.4 19808 8092 ?        S    09:04   0:00 [xxxxx]
apache    2100  0.0  6.4 19808 8092 ?        S    09:08   0:00 [xxxxx]
[cnscn@cnscn /home/cnscn]$ sed  -n  -e  /8092/s/httpd/xxxxx/gp tmp.txt | awk  '{print $1}' |uniq  -c
      7 apache


============================================================
#!/bin/sh
#awk.prog
#Func :  print $1 , then print $5 who's $1 is same ,  until the $1 is not same

sort|
awk '
        $1 == lastState {
                        print  "\t\t" $5
        }
        $1 != lastState {
                        lastState = $1
                        print  $1
        }' |
uniq -c

---------------------------------------------------------------------------------------------------------------------------------------

[cnscn@cnscn /home/cnscn]$ cat  tmp.txt | ./awk.prog | more
      1 apache
      3                 19808
      1                 19884
      1                 19808
      1 bin
      1 cnscn
      1                 5604
      1                 2632
      1 daemon
      1 root
      1                 1372
      2                 0
      1                 1444
      1                 1360

 » 相关连接:
scp远程copy文件
[回复]
.                   一个或多个字符(含换行符)
*                  零个或多个字符它前面的字符(包括由正则表达式指定的字符)
[...]              匹配其中的任一个字符
[^....]           匹配除[...]中字符外的所有字符
[x-z]             允许使用范围

^...              行以^后的内容开始
...$               行以$前的字符结尾

\{n,m\}         匹配字前面某个范围内单个字符出现的次数为n到m次之间
\{n,\}            匹配字前面某个范围内单个字符出现的次数为至少n次

=====================================================

+                 匹配前面的正则表达式的一次或多次出现
?                 匹配前面的正则表达式的零次或多次出现
|                 指定可以匹配其前面的或后面的正则表达式
()                对表达式进行分组
{n,m}          同\{n,m\}

\n               表示从0到9的数字


======================================================

[cnscn@cnscn /home/cnscn]$ grep '1.8'  tmp.txt
root      1789  0.0  6.3 19744 7976 ?        S    08:45   0:00 /usr/sbin/httpd
apache    1819  0.0  6.4 19808 8092 ?        S    08:45   0:00 [httpd]
apache    1820  0.0  6.4 19808 8092 ?        S    08:45   0:00 [httpd]
root      1981  0.0  0.0  1396  104 ?        SN   08:46   0:00 anacron -s
apache    2100  0.0  6.4 19808 8092 ?        S    09:08   0:00 [httpd]

=======================================================
[Ww]hat

\.H[12345]        匹配.H1 , .H2, .H3, .H4, .H5
grep  '\.H[123]'  tmp.txt
[a-ZA-Z0-9?,.;:'"+-*/]   注: []内只匹配单个字符
[0-9][0-9][-/][0-3][0-9][-/][0-9][0-9]
[^0-9]
[^aeuou]

=======================================================
[:alnum:]              可打印字符(含空白字符)
[:alpha:]               字母字符
[:blank:]               空格和制表符
[:cntrl:]                控制字符
[:digit:]                数字字符
[:graph:]              可打印的和可见的(非空格)字符
[:lower:]              小写字符
[:print:]                可打印字符
[:punct:]              标占字符
[:space:]              空白字符
[:upper:]             大写字符
[:xdigit:]              十六进制数字

=======================================================

grep  '<.*>'  tmp.txt  匹配所有的标记行
grep  "can [ no']*t"  tmp.txt        则匹配
cannot
can not
can't
cant

 » 相关连接:
scp远程copy文件
[回复]
·一次一行的sed的设计的优点:避免屏幕编辑程序一次读入内存可能产生的内存溢出或处理大文件时速度非常慢的产生

删除空行
/^$/d


范围删除:删除从bin到daemon之间的行(含)
sort tmp.txt | sed   /bin/,/daemon/d

5,$/d

1,/^$/d                           删除直到一个空行

/bin/,/daemon/{ /^$/d }   #范围{语句}

#aaa.sed
/bin/,/daemon/{
                           /^$/d
                         s/yao/yin/
                         s/^\.vs 12/\.vs 13/
}

---------------------------------------------
sed  -f aaa.sed  tmp.txt

 » 相关连接:
[回复]
sed [options] '{command}' [filename]

替换
sed  's/old/new/'

同时修改
sed   's/old/new/;s/old2/new2/'


假定希望用 "2" 来替换 "1",但仅在单词 "two" 之后才作替换,而不是每一行的所有位置。通过指定在给出替换命令之前必须存在一次匹配,可以实现这一点:
$ sed '/two/ s/1/2/' sample_one


现在,使其更加准确:



$ sed '> /two/ s/1/2/> /three/ s/1/3/' sample_one禁止显示 sed 默认将来自源文件的每一行显示到屏幕上(或重定向到一个文件中),而无论该行是否受到编辑操作的影响,"-n" 参数覆盖了这一操作。"-n" 覆盖了所有的显示,并且不显示任何一行,而无论它们是否被编辑操作修改。例如:  $ sed -n -f sedlist sample_one脚本$ cat sedlist/two/ s/1/2/p/three/ s/1/3/p   利用它的另一种方法是只显示一定数量的行。例如,只显示 2-6 行,同时不做其它的编辑修改:



$ sed -n '2,6p' sample_onetwo     1three   1one     1two     1two     1 从 sample_one 文件中删除包含 "two" 的所有行:



$ sed '/two/ d' sample_one 从显示屏中删除前三行,而不管它们的内容是什么:



$ sed '1,3 d' sample_oneone     1two     1two     1three   1
  1. 上三角号 (^) 表示一行的开始,因此,如果 "two" 是该行的头三个字符,则





    sed '/^two/ d' sample_one

    将只删除该行。
  2. 美元符号 ($) 代表文件的结尾,或一行的结尾,因此,如果 "two" 是该行的最后三个字符,则
sed '/two$/ d' sample_one

1)删除文件中的所有空白行。例如,以下命令将 "1" 替换为 "2",以及将 "1" 替换为 "3",并删除文件中所有尾随的空行:



$ sed '/two/ s/1/2/; /three/ s/1/3/; /^$/ d' sample_oneone     1two     1其通常的用途是删除一个标题。以下命令将删除文件中所有的行,从第一行直到第一个空行:



sed '1,/^$/ d' {filename}  添加和插入文本

可以结合使用 sed 和 "a" 选项将文本添加到一个文件的末尾。实现方法如下:



$ sed '$a\> This is where we stop\> the test' sample_oneone     1two     1three   1one     1two     1two     1three   1This is where we stopthe test$

在该命令中,美元符号 ($) 表示文本将被添加到文件的末尾。反斜线 (\) 是必需的,它表示将插入一个回车符。如果它们被遗漏了,则将导致一个错误,显示该命令是错乱的;在任何要输入回车的地方您必须使用反斜线。

要将这些行添加到第 4 和第 5 个位置而不是末尾,则命令变为:



$ sed '3a\> This is where we stop\> the test' sample_oneone     1two     1three   1This is where we stopthe testone     1two     1two     1three   1$

这将文本添加到第 3 行之后。和几乎所有的编辑器一样,您可以选择插入而不是添加(如果您希望这样的话)。这两者的区别是添加跟在指定的行之后,而插入从指定的行开始。当用插入来代替添加时,只需用 "i" 来代替 "a",如下所示:



$ sed '3i\> This is where we stop\> the test' sample_oneone     1two     1This is where we stopthe testthree   1one     1two     1two     1three   1$

新的文本出现在输出的中间位置,而处理通常在指定的操作执行以后继续进行。


读写文件

重定向输出的功能已经演示过了,但需要指出的是,在编辑命令运行期间可以同步地读入和写出文件。例如,执行替换,并将 1-3 行写到名称为 sample_three 的文件中:



$ sed '> /two/ s/1/2/> /three/ s/1/3/> 1,3 w sample_three' sample_oneone     1two     2three   3one     1two     2two     2three   3$$ cat sample_threeone     1two     2three   3$

由于为 w (write) 命令指定了 "1,3",所以只有指定的行被写到了新文件中。无论被写的是哪些行,所有的行都在默认输出中显示。

修改命令

除了替换项目之外,还可以将行从一个值修改为另一个值。要记住的是,替换是对字符逐个进行,而修改功能与删除类似,它影响整行:



$ sed '/two/ c\> We are no longer using two' sample_oneone     1We are no longer using twothree   1one     1We are no longer using twoWe are no longer using twothree   1$

修改命令与替换的工作方式很相似,但在范围上要更大些—将一个项目完全替换为另一个项目,而无论字符内容或上下文。夸张一点讲,当使用替换时,只有字符 "1" 被字符 "2" 替换,而当使用修改时,原来的整行将被修改。在两种情况下,要寻找的匹配条件都仅为 "two"。

修改全部但……

对于大多数 sed 命令,详细说明各种功能要进行何种修改。利用感叹号,可以在除指定位置之外的任何地方执行修改—与默认的操作完全相反。

例如,要删除包含单词 "two" 的所有行,操作为:



$ sed '/two/ d' sample_oneone     1three   1one     1three   1$

而要删除除包含单词 "two" 的行之外的所有行,则语法变为:



$ sed '/two/ !d' sample_onetwo     1two     1two     1$

如果您有一个文件包含一系列项目,并且想对文件中的每个项目执行一个操作,那么首先对那些项目进行一次智能扫描并考虑将要做什么是很重要的。为了使事情变得更简单,您可以将 sed 与任意迭代例程(for、while、until)结合来实现这一目的。

比如说,假定您有一个名为 "animals" 的文件,其中包含以下项目:

pig
horse
elephant
cow
dog
cat


您希望运行以下例程:



#mcd.kshfor I in $*doecho Old McDonald had a $Iecho E-I, E-I-Odone

结果将为,每一行都显示在 "Old McDonald has a" 的末尾。虽然对于这些项目的大部分这是正确的,但对于 "elephant" 项目,它有语法错误,因为结果应当为 "an elephant" 而不是 "a elephant"。利用 sed,您可以在来自 shell 文件的输出中检查这种语法错误,并通过首先创建一个命令文件来即时地更正它们:



#sublist/ a a/ s/ a / an // a e/ s/ a / an //a i/ s / a / an //a o/ s/ a / an //a u/ s/ a / an /

然后执行以下过程:



$ sh mcd.ksh 'cat animals' | sed -f sublist  

现在,在运行了 mcd 脚本之后,sed 将在输出中搜索单个字母 a (空格,"a",空格)之后紧跟了一个元音的任意位置。如果这种位置存在,它将把该序列修改为空格,"an",空格。这样就使问题更正后才显示在屏幕上,并确保各处的编辑人员在晚上可以更容易地入睡。结果是:

Old McDonald had a pig
E-I, E-I-O
Old McDonald had a horse
E-I, E-I-O
Old McDonald had an elephant
E-I, E-I-O
Old McDonald had a cow
E-I, E-I-O
Old McDonald had a dog
E-I, E-I-O
Old McDonald had a cat
E-I, E-I-O


提前退出

sed 默认读取整个文件,并只在到达末尾时才停止。不过,您可以使用退出命令提前停止处理。只能指定一条退出命令,而处理将一直持续直到满足调用退出命令的条件。

例如,仅在文件的前五行上执行替换,然后退出:



$ sed '> /two/ s/1/2/> /three/ s/1/3/> 5q' sample_oneone     1two     2three   3one     1two     2$

在退出命令之前的项目可以是一个行号(如上所示),或者一条查找/匹配命令:



$ sed '> /two/ s/1/2/> /three/ s/1/3/> /three/q' sample_oneone     1two     2three   3$

您还可以使用退出命令来查看超过一定标准数目的行,并增加比 head 中的功能更强的功能。例如,head 命令允许您指定您想要查看一个文件的前多少行—默认数为 10,但可以使用从 1 到 99 的任意一个数字。如果您想查看一个文件的前 110 行,您用 head 不能实现这一目的,但用 sed 可以:



sed 110q filename

处理问题

当使用 sed 时,要记住的重要事项是它的工作方式。它的工作方式是:读入一行,在该行上执行它已知要执行的所有任务,然后继续处理下一行。每一行都受给定的每一个编辑命令的影响。

如果您的操作顺序没有十分彻底地考虑清楚,那么这可能会很麻烦。例如,假定您需要将所有的 "two" 项目修改为 "three",然后将所有的 "three" 修改为 "four":



$ sed '> /two/ s/two/three/> /three/ s/three/four/' sample_oneone     1four     1four   1one     1four     1four     1four   1$

最初读取的 "two" 被修改为 "three"。然后它满足为下一次编辑建立的准则,从而变为 "four"。最终的结果不是想要的结果—现在除了 "four" 没有别的项目了,而本来应该有 "three" 和 "four"。

当执行这种操作时,您必须非常用心地注意指定操作的方式,并按某种顺序来安排它们,使得操作之间不会互相影响。例如:



$ sed '> /three/ s/three/four/> /two/ s/two/three/' sample_oneone     1three     1four   1one     1three     1three     1four   1$

这非常有效,因为 "three" 值在 "two" 变成 "three" 之前得到修改。

标签和注释

可以在 sed 脚本文件中放置标签,这样一旦文件变得庞大,可以更容易地说明正在发生的事情。存在各种各样与这些标签相关的命令,它们包括:


  1. : 冒号表示一个标签名称。例如:



    :HERE

    以冒号开始的标签可以由 "b" 和 "t" 命令处理。


  2. b {label} 充当 "goto" 语句的作用,将处理发送至前面有一个冒号的标签。例如,



    b HERE

    将处理发送给行



    :HERE

    如果紧跟 b 之后没有指定任何标签,则处理转至脚本文件的末尾。


  3. t {label} 只要自上次输入行或执行一次 "t" 命令以来进行了替换操作,就转至该标签。和 "b" 一样,如果没有给定标签名,则处理转至脚本文件的末尾。


  4. # 符号作为一行的第一个字符将使整行被当作注释处理。注释行与标签不同,不能使用 b 或 t 命令来转到注释行上。

进一步的研究
sed 实用工具是 Linux 管理员拥有的最强大和灵活的工具之一。虽然本文覆盖了许多基础知识,但对于这一具有丰富功能的工具仅是蜻蜓点水。关于更多信息,最好的来源之一是 Dale Dougherty 和 Arnold Robbins 的著作 sed & awk,现在从 O'Reilly & Associates 出版社推出了其第二版(参加“接下来的步骤”)。该出版社还推出了一本可以随身携带的袖珍参考。




</SPAN>

 » 相关连接:
[回复]
·在行首加上' ',并存成文件
$ sed   s/^/\' \',/  id_pass.txt  >abc.txt


$ df -k | awk '{print $1}'| grep -v "Filesystem"
文件系统
/dev/sda2
/dev/sda1
none




$ df -k | awk '{print $1}'| grep -v "Filesystem" | sed s'/\/dev\///g'
文件系统
sda2
sda1
none

去掉多余的回车符
sed s/^M// test.sh > back.sh, 注意^M是敲ctrl_v ctrl-m得到的
或者 dos2unix filename

 » 相关连接:
[回复]
#!/bin/sh

while read old

do

new=`echo $old|sed '

h

s:.*/::

s: :_:g

G

s:\(.*\)\n\(.*/\).*:\2\1:'`

mv "$old" "$new"

done

上面的代码是用来将文件名中的空格替换成_的,但是具体的一行一行代码看不懂,望高手指点一下!!!!!!!

由 freefall 在 11-17-2004 14:32 发表:



h
===>把文件中的空格hold
s:.*/::
===>相当于把/home/yourname/filename hello替换成filename hello
s: :_:g
===>把空格替换成_,filename hello变成filename_hello
G
===>增加一行,变成
filename_hello
/home/yourname/filename_hello
s:\(.*\)\n\(.*/\).*:\2\1:
===>\(.*\)对应\2,换行符前的任意多字符,\(.*/\)对应\1,即第二行的/home/yourname/


PS:希望有说清楚,对你有帮助。不妨自己实验
如:echo "/home/yourname/filename hello"|sed 'h'
echo "/home/yourname/filename hello"|sed 'h;s:.*/::'

由 max_xy 在 11-17-2004 14:54 发表:



3x a lot

由 max_xy 在 11-17-2004 17:00 发表:



翻阅了一下《sed&awk》那本书,结合freefall的帖子,这里给出自己的一点体会,希望各位指正。
h
=======>The hold command copies the current input line into the hold space.
Pattern space:/home/yourname/filename hello
Hold space:/home/yourname/filename hello
s:.*/::
===>相当于把/home/yourname/filename hello替换成filename hello
Pattern space:filename hello
Hold space:/home/yourname/filename hello
s: :_:g
===>把空格替换成_,filename hello变成filename_hello
Pattern space:filename_hello
Hold space:/home/yourname/filename hello
G
====>The Get command appends the line saved in the hold space to the pattern space.
Pattern space:
filename_hello\n/home/yourname/filename hello
Hold

 » 相关连接:
[回复]
将a.txt内的cccc换成当前的日期
sed -i 's/cccc/'`date +%F`'/g' a.txt


//去掉" 并进行uniq排序
#sed  "s/\"//g"    56.csv  | sort -u  | more

 » 相关连接:
« 1 2» Pages: ( 1/2 total )
 » 本栏目最新帖:
 » 精华帖:

Powered by PHPWind v6.0 Code © 2003-08