少年阿宾

那些青春的岁月

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
1、sed使用手册(转载) 

sed使用手册(转载) 
发信站: BBS 水木清华站 (Wed Sep 25 21:06:36 2002), 站内信件 
 
 
 
  Sed 命令列可分成编辑指令与文件档部份。其中 , 编辑指令负责控制所有的编 
辑工作 ; 文件档表示所处理的档案。  
  sed 的编辑指令均由位址(address)与函数(function)两部份组成 , 其中 , 在 
执行时 , sed 利用它的位址参数来  
  决定编辑的对象;而用它的函数参数(解[3])编辑。   
  此外 , sed 编辑指令 , 除了可在命令列上执行 , 也可在档案内执行。其中差 
别只是在命令列上执行时 , 其前必  
  须加上选项 -e ; 而在档案(解[4])内时 , 则只需在其档名前加上选项 -f。另 
外 , sed 执行编辑指令是依照它  
  们在命令列上或档内的次序。   
 
  下面各节 , 将介绍执行命令列上的编辑指令 、sed 编辑指令、执行档案内的编 
辑指令、执行多个档案的编辑、及  
  执行 sed 输出控制。   
 
2.1 执行命令列上的编辑指令   
2.2 sed 编辑指令   
2.3 执行档案内的编辑指令   
2.4 执行多个档案的编辑   
2.5 执行 sed 输出控制   
2.1.执行命令列上的编辑指令   
  当编辑指令(参照[section 2.2])在命令列上执行时 , 其前必须加上选项 -e 。 
其命令格式如下 :   
 
    sed -e '编辑指令1' -e '编辑指令2' ... 文件档    
 
其中 , 所有编辑指令都紧接在选项 -e 之後 , 并置於两个 " ' " 特殊字元间。 
另外 , 命令上编辑指令的执行是由  
左而右。  
 
  一般编辑指令不多时 , 使用者通常直接在命令上执行它们。例如 , 删除 yel. 
dat 内 1 至 10 行资料 , 并将其  
  馀文字中的 "yellow" 字串改成 "black" 字串。此时 , 可将编辑指令直接在命 
令上执行 , 其命令如下 :   
 
    sed -e '1,10d' -e 's/yellow/black/g' yel.dat    
 
在命令中 , 编辑指令 '1,10d'(解[5])执行删除 1 至 10 行资料 ; 编辑指令  
's/yellow/black/g'(解[6]) ,   
"yellow" 字串替换(substuite)成 "black" 字串。   
2.2 sed 的编辑指令   
  sed 编辑指令的格式如下 :   
             [address1[,address2]]function[argument]  
 
其中 , 位址参数 address1 、address2 为行数或 regular expression 字串 ,  
表示所执行编辑的资料行 ; 函数参  
数 function[argument] 为 sed 的内定函数 , 表示执行的编辑动作。   
下面两小节 , 将仔细介绍位址参数的表示法与有哪些函数参数供选择。   
 
2.2.1 位址(address)参数的表示法  
  实际上 , 位址参数表示法只是将要编辑的资料行 , 用它们的行数或其中的字串 
来代替表示它们。下面举几个例子  
  说明(指令都以函数参数 d(参照[section4.2]) 为例) :   
删除档内第 10 行资料 , 则指令为 10d。   
删除含有 "man" 字串的资料行时 , 则指令为 /man/d。   
删除档内第 10 行到第 200 行资料, 则指令为 10,200d。   
 
删除档内第 10 行到含 "man" 字串的资料行 , 则指令为 10,/man/d。   
  接下来 , 以位址参数的内容与其个数两点 , 完整说明指令中位址参数的表示法 
(同样也以函数参数 d 为例)。   
位址参数的内容:   
位址为十进位数字 : 此数字表示行数。当指令执行时 , 将对符合此行数的资料执 
行函数参数指示的编辑动作。例如 ,   
删除资料档中的第 15 行资料 , 则指令为 15d(参照[section4.2])。其馀类推 , 
如删除资料档中的第 m 行资料 , 则  
指令为 md 。   
 
位址为 regular expression(参照[附录 A]):  
当资料行中有符合 regular expression 所表示的字串时 , 则执行函数参数指示 
的编辑动作。另外 , 在   
regular expression 前後必须加上 "/"。例如指令为 /t.*t/d , 表示删除所有含 
两 "t" 字母的资料行。其中 , "."   
表示任意字元; "*" 表示其前字元可重任意次 , 它们结合 ".*" 表示两 "t" 字母 
间的任意字串。   
 
位址参数的个数 : 在指令中 , 当没有位址参数时 , 表示全部资料行执行函数参 
数所指示的编辑动作; 当只有一位址  
参数时 , 表示只有符合位址的资料行才编辑 ; 当有两个位址参数 , 如  
address1,address2 时 , 表示对资料区执行  
编辑 , address1 代表起始资料行 , address2 代表结束资料行。对於上述内容 , 
 以下面例子做具说明。   
 
例如指令为   
  
d   
 
其表示删除档内所有资料行。   
例如指令为   
  
5d   
 
其表示删除档内第五行资料。   
例如指令为   
  
1,/apple/d  
 
其表示删除资料区 , 由档内第一行至内有 "apple" 字串的资料行。   
例如指令为   
  
/apple/,/orange/d   
 
其表示删除资料区 , 由档内含有 "apple" 字串至含有 "orange" 字串的资料行  
  
2.2.2 有那些函数(function)参数   
  下页表中介绍所有 sed 的函数参数(参照[chapter 4])的功能。  
函数参数 功能   
∶ label  建立 script file 内指令互相参考的位置。    
#  建立解    
{ }  集合有相同位址参数的指令。    
!  不执行函数参数。    
=  印出资料行数( line number )。    
a  添加使用者输入的资料。    
b label  将执行的指令跳至由 : 建立的参考位置。    
c  以使用者输入的资料取代资料。   
 
d  删除资料。    
D  删除 pattern space 内第一个 newline 字母 前的资料。    
g  拷贝资料从 hold space。    
G  添加资料从 hold space 至 pattern space 。    
h  拷贝资料从 pattern space 至 hold space 。    
H  添加资料从 pattern space 至 hold space 。    
l  印出 l 资料中的 nonprinting character 用 ASCII 码。    
i  插入添加使用者输入的资料行。    
n  读入下一笔资料。    
N  添加下一笔资料到 pattern space。    
p  印出资料。    
P  印出 pattern space 内第一个 newline 字母 前的资料。    
q  跳出 sed 编辑。    
r  读入它档内容。    
s  替换字串。    
t label  先执行一替换的编辑指令 , 如果替换成牛p>则将编辑指令跳至 : label 
 处执行。    
w  写资料到它档内。    
x  交换 hold space 与 pattern space 内容。    
y  转换(transform)字元。    
虽然 , sed 只有上表所述几个拥有基本编辑功能的函数 , 但由指令中位址参数和 
指令与指令间的配合 , 也能使   
sed 完成大部份的编辑任务。   
2.3 执行档案内的编辑指令   
  当执行的指令太多 , 在命令列上撰写起来十分混乱 , 此时 , 可将这些指令整 
理储存在档案  
  (譬如档名为 script_file )内 , 用选项 -f script_file , 则让 sed 执行  
script_file 内的编辑指令。其命  
  令的格示如下 :   
     sed -f script_file 文件档    
 
其中 , 执行 script_file 内编辑指令的顺序是由上而下。例如上一节的例子 ,  
其可改成如下命令:   
     sed -f ysb.scr yel.dat    
 
其中 , ysb.scr 档的内容如下 :   
1,10d  
s/yellow/black/g  
 
  另外 , 在命令列上可混合使用选项 -e 与 -f , sed 执行指令顺序依然是由命 
令列的左到右, 如执行至 -f 後  
  档案内的指令 , 则由上而下执行。   
 
 
2.4 执行多个文件档的编辑   
  在 sed 命令列上 , 一次可执行编辑多个文件档 , 它们跟在编辑指令之後。例 
如 , 替换  
   white.dat、red.dat、black.dat 档内的 "yellow" 字串成 "blue" , 其命令 
如下:   
      sed -e 's/yellow/blue/g' white.dat red.dat black.dat   
 
上述命令执行时 , sed 依 white.dat、red.dat、black.dat 顺序 , 执行编辑指 
令 s/yellow/blue/(请参照[section 4.1] ,   
进行字串的替换。  
 
2.5.执行输出的控制   
  在命令列上的选项 -n (解[7]) 表示输出由编辑指令控制。由前章内容得知 ,  
sed 会 "自动的" 将资料由  
   pattern space 输送到标准输出档。但藉着选项 -n , 可将 sed 这 "自动的 
" 的动作改成 "被动的" 由它所执行的  
   编辑指令(解[8])来决定结果是否输出。   
  由上述可知 , 选项 -n 必须与编辑指令一起配合 , 否则无法获得结果。例如 , 
 印出 white.dat 档内含有 "white"   
  字串的资料行 , 其命令如下:   
 
      sed -n -e '/white/p' white.dat     
 
上面命令中 , 选项 -n 与编辑指令 /white/p (参照[section4.6]) 一起配合控制 
输出。其中 , 选项 -n 将输出控制权  
移给编辑指令;/white/p 将资料行中含有 "white" 字串印出萤幕。    
 

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

1.sed -n '2'p filename 
打印文件的第二行。

2.sed -n '1,3'p filename 
打印文件的1到3行

3. sed -n '/Neave/'p filename 
打印匹配Neave的行(模糊匹配)

4. sed -n '4,/The/'p filename 
在第4行查询模式The

5. sed -n '1,$'p filename 
打印整个文件,$表示最后一行。

6. sed -n '/.*ing/'p filename 
匹配任意字母,并以ing结尾的单词(点号不能少)

7 sed -n / -e '/music/'= filename 
打印匹配行的行号,-e 会打印文件的内容,同时在匹配行的前面标志行号。-n只打印出实际的行号。

8.sed -n -e '/music/'p -e '/music/'= filename 
打印匹配的行和行号,行号在内容的下面

9.sed '/company/' a "Then suddenly it happend" filename 
选择含有company的行,将后面的内容"Then suddenly it happend"加入下一行。注意:它并不改变文件,所有

操作在缓冲区,如果要保存输出,重定向到一个文件。

10. sed '/company/' i "Then suddenly it happend" filename 
同9,只是在匹配的行前插入

11.sed '/company/' c "Then suddenly it happend" filename 
用"Then suddenly it happend"替换匹配company的行的内容。

12.sed '1'd ( '1,3'd '$'d '/Neave/'d) filename 
删除第一行(1到3行,最后一行,匹配Neave的行)

13.[ address [,address]] s/ pattern-to-find /replacement-pattern/[g p w n] 
s选项通知s e d这是一个替换操作,并查询pattern-to-find,成功后用replacement-pattern替换它。 
替换选项如下: 
g 缺省情况下只替换第一次出现模式,使用g选项替换全局所有出现模式。 
p 缺省s e d将所有被替换行写入标准输出,加p选项将使- n选项无效。- n选项不打印输出结果。 
w 文件名使用此选项将输出定向到一个文件。(注意只将匹配替换的行写入文件,而不是整个内容)

14.sed s'/nurse/"hello "&/' filename 
将'hello '增加到'nurse' 的前面。

15. sed '/company/r append.txt' filename 
在匹配company的行的下一行开始加入文件append.txt的内容。

16. sed '/company/'q filename 
首次匹配company后就退出sed程序

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


sed 's/abc/123/g' myfile

sed -n 's/^west/north/p' myfile
打印替换了west开头用north替换的行

sed -n '/aa/,/bb/p' myfile
打印在包含以aa开头到以bb结束的行

sed '1,4s/aa/bb/g' myfile

sed '4,/aa/s/11/22/g' myfile
在第4行后到包含aa结束的行中,替换11为22

sed 'aa/,/bb/s/11/22/g' myfile
在包含以aa开头到以bb结束的行中,替换11为22

sed '1,5s/$/cc/' myfile
每行的末尾以cc来替换

--e-----------------------
sed -e '1,3d' -e 's/aa/bb/' myfile
对myfile同时执行d 与s 操作

--w-----------------------
sed -n '/north/w newfile' myfile
把myfile中包含north的行写入newfile中

--a-----------------------
sed '/^north /a \
----->add string------------------' myfile
往myfiel追加行

--i-----------------------
sed '/aa/i\
new line1--------------
------------new line2--------------' myfile

在包含/aa的行下插入行

--n--------------------
sed /aa/{n;s/11/22/;} myfile
找到包含aa的行后,对下一行执行s操作

--y--------------------

sed 1,3y/abcdefg/ABCDEFG' myfile
在1,3行中把abcdefg变形为ABCDEFG

--q---------------------
sed '5q' myfile
推出命令。执行到5行后退出

--h 与 g,x--------------
sed -e '/aa/h' -e '$g' myfile
把包含aa的行放如缓冲区,在最后一行中增加(也就是把包含有aa的行追加到最后一行中)


sed -e '/aa/{h;d; }' -e '/bb/{g;}' myfile
把包含aa的行放入缓冲区,删除包含aa的行;找到bb的行后,把aa的行在后面追加

sed -e '/aa/h' -e '$g' myfile

sed -e '/aa/h' -e '/bb/x' myfile
把包含aa的行放入缓冲区,当出现/bb的行时,则把bb的内容换为缓冲区的内容

为了使用上述输出信息做进一步自动处理,需要知道所存数据库名称,为此需执行以下操作:
  1) 使用s / - * / / g删除横线- - - - - -。
  2) 使用/ ^ $ / d删除空行。
  3) 使用$ d删除最后一行
  4) 使用1 d删除第一行。
  5) 使用awk {print $1}打印第一列。
  命令如下,这里使用了c a t,并管道传送结果到s e d命令  
  最后的命令如下:
   cat sql.txt| sed 's/-*//g'|sed '/^$//g'|sed '$d'|sed '1d'|awk '{print $1}'
   
  去除行首数字:
   sed 's/^[0-9]//g' data.txt
   
10、一些常用的处理
  ‘s / \ . $ / / g’ 删除以句点结尾行
  ‘-e /abcd/d’ 删除包含a b c d的行
  ‘s / [ ] [ ] [ ] * / [ ] / g’ 删除一个以上空格,用一个空格代替
  ‘s / ^ [ ] [ ] * / / g’ 删除行首空格
  ‘s / \ . [ ] [ ] * / [ ] / g’ 删除句点后跟两个或更多空格,代之以一个空格
  ‘/ ^ $ / d’ 删除空行
  ‘s / ^ . / / g’ 删除第一个字符
  ‘s /CO L \ ( . . . \ ) / / g’ 删除紧跟C O L的后三个字母
  ‘s / ^ \ / / / g’ 从路径中删除第一个\
  ‘s / [ ] / [ ] / / g’ 删除所有空格并用t a b键替代
  ‘S / ^ [ ] / / g’ 删除行首所有t a b键
  ‘s / [ ] * / / g’ 删除所有t a b键

2、关于tr
   通过使用 tr,您可以非常容易地实现 sed 的许多最基本功能。您可以将 tr 看作为 sed 的(极其)简化的变体:它可以用一个字符来替换另一个字符,或者可以完全除去一些字符。您也可以用它来除去重复字符。这就是所有 tr 所能够做的。 
       tr用来从标准输入中通过替换或删除操作进行字符转换。tr主要用于删除文件中控制字符或进行字符转换。使用tr时要转换两个字符串:字符串1用于查询,字符串2用于处理各种转换。tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。
带有最常用选项的tr命令格式为:
tr -c -d -s ["string1_to_translate_from"] ["string2_to_translate_to"] < input-file
这里:
-c 用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。
-d 删除字符串1中所有输入字符。
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
input-file是转换文件名。虽然可以使用其他格式输入,但这种格式最常用。
2、字符范围
指定字符串1或字符串2的内容时,只能使用单字符或字符串范围或列表。
[a-z] a-z内的字符组成的字符串。
[A-Z] A-Z内的字符组成的字符串。
[0-9] 数字串。
\octal 一个三位的八进制数,对应有效的ASCII字符。
[O*n] 表示字符O重复出现指定次数n。因此[O*2]匹配OO的字符串。
tr中特定控制字符的不同表达方式
速记符含义八进制方式
\a Ctrl-G  铃声\007
\b Ctrl-H  退格符\010
\f Ctrl-L  走行换页\014
\n Ctrl-J  新行\012
\r Ctrl-M  回车\015
\t Ctrl-I  tab键\011
\v Ctrl-X  \030
3、应用例子
(1)去除oops.txt里面的重复的小写字符
tr -s "[a-z]"<oops.txt >result.txt
(2)删除空行
tr -s "[\012]" < plan.txt 或 tr -s ["\n"] < plan.txt
(3)有时需要删除文件中的^M,并代之以换行
tr -s "[\015]" "[\n]" < file 或 tr -s "[\r]" "[\n]" < file
(4)大写到小写
cat a.txt |tr "[a-z]" "[A-Z]" >b.txt
(5)删除指定字符
    一个星期的日程表。任务是从其中删除所有数字,只保留日期。日期有大写,也有小写格式。因此需指定两个字符范围[a-z]和[A-Z],命令tr -cs "[a-z][A-Z]" "[\012*]" 将文件每行所有不包含在[a-z]或[A-Z](所有希腊字母)的字符串放在字符串1中并转换为一新行。-s选项表明压缩所有新行, -c表明保留所有字母不动。原文件如下,后跟tr命令:
tr -cs "[a-z][A-Z]" "[\012*]" <diary.txt
(6)转换控制字符
    tr的第一个功能就是转换控制字符,特别是从dos向UNIX下载文件时,忘记设置ftp关于回车换行转换的选项时更是如此。cat -v filename 显示控制字符。
    cat -v stat.txt
    box aa^^^^^12^M
    apple bbas^^^^23^M
    ^Z
猜想‘^ ^ ^ ^ ^ ^’是tab键。每一行以Ctrl-M结尾,文件结尾Ctrl-Z,以下是改动方法。
使用-s选项,查看ASCII表。^的八进制代码是136,^M是015,tab键是011,^Z是032 ,下面将按步骤完成最终功能。
用tab键替换^ ^ ^ ^ ^ ^,命令为"\136" "[\011*]"。将结果重定向到临时工作文件stat.tmp
tr -s "[\136]" "[\011*]" <stat.txt >stat.tmp
用新行替换每行末尾的^M,并用\n去除^Z,输入要来自于临时工作文件stat.tmp。
tr -s "[\015][\032]" "\n" <stat.tmp
要删除所有的tab键,代之以空格,使用命令
tr -s "[\011]" "[\040*]" <input.file
(7)替换passwd文件中所有冒号,代之以tab键,可以增加可读性
tr -s "[:]" "[\011]" < /etc/passwd 或 tr -s "[:]" "[\t]" < /etc/passwd
(8)使路径具有可读性
    如果用 echo $PATH 或者 echo $LD_LIBRARY_PATH 等类似的命令来显示路径信息的话,我们看到的将会是一大堆用冒号连接在一起的路径, tr命令可以把这些冒号转换为回车,这样,这些路径就具有很好的可读性了
echo $PATH | tr ":" "\n" 
(9)可以在vi内使用所有这些命令!只要记住:在tr命令前要加上您希望处理的行范围和感叹号 (!),如 1,$!tr -d '\t'(美元符号表示最后一行)。
(10)另外,当有人给您发送了一个在 Mac OS 或 DOS/Windows 机器上创建的文本文件时,您会发现tr非常有用。
    如果没有将文件保存为使用  UNIX 换行符来表示行结束这种格式,则需要将这样的文件转换成本机 UNIX 格式,否则一些命令实用程序不会正确地处理这些文件。Mac OS  的行尾以回车字符(\r)结束,许多文本处理工具将这样的文件作为一行来处理。为了纠正这个问题,可以用下列技巧: 
Mac -> UNIX:tr "\r" "\n"<macfile > unixfile
UNIX -> Mac:tr "\n" "\r"<unixfile > macfile
Microsoft DOS/Windows 约定,文本的每行以回车字符(\r)并后跟换行符(\n)结束。为了纠正这个问题,可以使用下列命令: 
DOS -> UNIX:tr -d "\r"<dosfile > unixfile
UNIX -> DOS:在这种情况下,需要用awk,因为tr不能插入两个字符来替换一个字符。要使用的 awk 命令为 awk '{ print $0"\r" }'<unixfile > dosfile
注:都可以用sed 来完成。
3、sort uniq join cut paste split
  ================sort用法=====================
 sort命令将许多不同的域按不同的列顺序分类。
1、sort选项
 sort命令的一般格式为:
  sort -cmu -o output_file [other options] +pos1 +pos2 input_files
  下面简要介绍一下s o r t的参数:
  -c 测试文件是否已经分类。
  -m 合并两个分类文件。
  -u 删除所有复制行。
  -o 存储s o r t结果的输出文件名。
  其他选项有:
  -b 使用域进行分类时,忽略第一个空格。
  -n 指定分类是域上的数字分类。
  -t 域分隔符;用非空格或t a b键分隔域。
  -r 对分类次序或比较求逆。
  +n n为域号。使用此域号开始分类。
  n n为域号。在分类比较时忽略此域,一般与+ n一起使用。
  post1 传递到m,n。m为域号,n为开始分类字符数;例如4,6意即以第5域分类,从第7个字符开始。
2、sort启动方式
  缺省情况下, s o r t认为一个空格或一系列空格为分隔符。要加入其他方式分隔,使用- t选项。
  sort执行时,先查看是否为域分隔设置了- t选项,如果设置了,则使用它来将记录分隔成域0、域1等等;
 如果未设置,用空格代替。缺省时s o r t将整个行排序,指定域号的情况例外。
  关于s o r t的一个重要事实是它参照第一个域作为域0,域1是第二个域,等等。
3、文件是否已分类
  sort -c data.txt
4、sort分类求逆
 如果要逆向s o r t结果,使用-r选项。
   sort -t: -r video.txt
5、按指定域分类
 有时需要只按第2域(分类键1)分类。
  sort -t: +1 video.txt
6、数值域分类
 用-n选项。必须用,不然得不到想要的结果。
  sort -t: +3n video.txt
7、唯一性分类
 使用- u选项进行唯一性(不重复)分类以去除重复行。
8、使用k的其他sort方法
 sort还有另外一些方法指定分类键。可以指定k选项。
  sort -t: -k4 video.txt
  
 使用k做分类键排序:  
 可以指定分类键次序。先以第4域,再以第1域分类,命令为-k4 -k1
  sort -t: -k4 -k1 video.txt
9、指定sort序列
 可以指定分类键顺序,也可以使用- n选项指定不使用哪个分类键进行查询。看下面的sort命令:
  sort +0 -2 +3
 该命令意即开始以域0分类,忽略域2,然后再使用域3分类。
10、pos用法
 指定开始分类的域位置的另一种方法是使用如下格式:
  sort  +filed.characterin
 意即从filed开始分类,但是要在此域的第characterin个字符开始。 
11、使用head和tail将输出分类
  可以使用h e a d或t a i l查阅任何大的文本文件 
  head -200 filename
12、awk使用sort输出结果
13、将两个分类文件合并
  将文件合并前,它们必须已被分类.
  使用-m +0。将这个文件并入已存在的分类文件v i d e o . s o r t,要以名称域进行分类,实际上没有必要加入+ o,但为了保险起见,还是加上的好。
   sort -t: -m +0 video2.txt video.sort
   
   ===================uniq用法====================
  uniq用来从一个文本文件中去除或禁止重复行。一般u n i q假定文件已分类,并且结果正确。
  sort的唯一性选项去除所有重复行,而uniq命令并不这样做。重复行是什么?在uniq里意即持续不断重复出现的行,中间不夹杂任何其他文本.
  命令一般格式:
   uniq -u d c -f inputfile outputfile
  其选项含义:
   -u 只显示不重复行。
   -d 只显示有重复数据行,每种重复行只显示其中一行
   -c 打印每一重复行出现次数。
   -f n为数字,前n个域被忽略。
   一些系统不识别- f选项,这时替代使用- n。
  对特定域进行测试:
  使用- n只测试一行一部分的唯一性。例如- 5意即测试第5域后各域唯一性。域从1开始记数。
 如果忽略第1域,只测试第2域唯一性,使用- n 2,下述文件包含一组数据,其中第2域代表组代码。
   uniq -f2 parts.txt或
   uniq -n2 parts.txt
  ==================join用法(强大呀,像sql里面的join 呢)========================
 join用来将来自两个分类文本文件的行连在一起。
 下面讲述join工作方式。这里有两个文件f i l e 1和f i l e 2,当然已经分类。每个文件里都有一
些元素与另一个文件相关。由于这种关系, join将两个文件连在一起,这有点像修改一个主文
件,使之包含两个文件里的共同元素。
 为有效使用join,需分别将输入文件分类:
 join的格式: 
  join [option] file1,file2
  an n 为一数字,用于连接时从文件n中显示不匹配行。例如, -a1显示第一个文件的不匹
 配行,- a2为从第二个文件中显示不匹配行。
  o n.m n为文件号,m为域号。1.3表示只显示文件1第三域,每个n,m必须用逗号分隔,
 如1.3,2.1。
  j n m   n为文件号,m为域号。使用其他域做连接域
  t  域分隔符。用来设置非空格或t a b键的域分隔符。例如,指定冒号做域分隔符- t:
  
 连接域为域0,缺省join删除或去除连接键的第二次重复出现:
   join names.txt town.txt
 1、不匹配连接,下面的例子显示匹配及不匹配域
   join -a1 -a2 names.txt town.txt
  只显示第一个文件中不匹配行:
   join -a1 names.txt town.txt
 2、选择性连接
 使用- o选项选择连接域。例如要创建一个文件仅包含人名及城镇, j o i n执行时需要指定显示域。方式如下:
 使用1 . 1显示第一个文件第一个域,2 . 2显示第二个文件第二个域,其间用逗号分隔。命令为:
   join -o 1.1,2.2 names.txt town.txt
 使用-jn m进行其他域连接,例如用文件1域3和文件2域2做连接键,命令为:
   join -j1 3 -j2 2 names.txt town.txt
 
 ===========================cut用法=========================================
 cut用来从标准输入或文本文件中剪切列或域。剪切文本可以将之粘贴到一个文本文件。
 cut一般格式为:
 cut [options] file1 file2
 下面介绍其可用选项:
 -c list 指定剪切字符数。
 -f field 指定剪切域数。
 -d 指定与空格和t a b键不同的域分隔符。
 -c 用来指定剪切范围,如下所示:
 -c 1,5-7 剪切第1个字符,然后是第5到第7个字符。
 -c1-50 剪切前5 0个字符。
 -f 格式与- c相同。
 -f 1,5 剪切第1域,第5域。
 - f 1,10-12 剪切第1域,第1 0域到第1 2域。
 
 剪切指定域:
 cut命令中剪切各域需用逗号分隔,如剪切域1和3,可以使用:
  cut -d: -f1,3 pers
 
 =========================paste用法==========================================
  cut用来从文本文件或标准输出中抽取数据列或者域,然后再用paste可以将这些数据粘贴
 起来形成相关文件。粘贴两个不同来源的数据时,首先需将其分类,并确保两个文件行数相同。
  paste将按行将不同文件行信息放在一行。缺省情况下,paste连接时,用空格或t a b键分隔
 新行中不同文本,除非指定- d选项,它将成为域分隔符。
  paste格式为;
   paste -d -s -file1 file2
 选项含义如下:
  -d 指定不同于空格或t a b键的域分隔符。例如用@分隔域,使用- d @。
  -s 将每个文件合并成行而不是按行粘
  
 paste命令管道输入:
 paste命令还有一个很有用的选项( -)。意即对每一个( -),从标准输入中读一次数据。
 使用空格作域分隔符,以一个4列格式显示目录列表。方法如下:
   ls |paste -d":" - - - -
 =========================split用法==========================================
  split用来将大文件分割成小文件。
  
 split -output_file-size input-filename output-filename
 每个文件格式为x [ a a ]到x [ z z ],x为文件名首字母, [ a a ]、[ z z ]为文件名剩余部分顺序字符组合.
   split -5000 url_access_user.txt splitfile
 
 
UNIX下用awk对话单统计日消费额
 
=============================================================
1、用awk实现按照电话号码进行统计
=============================================================
一般情况下,电话公司从交换机采集后将生成定长的话单文件,文件名也有一定的格式,如笔者正要处理的话单格式如下:
[zengzc@ZCBILL bill_data]$ cat Ticket_20041210_11
87881141,10,10,120,  0,20041210092920
87881142,10,30,230,-10,20041210092920
87881143,10,30,100,-20,20041210092920
87881143,10,30,110, 10,20041210093825
87881143,10,40, 90,  0,20041210095005
87881146,10,15, 45,  0,20041210092525
87881130,10,15, 80,  0,20041210092525
87881131,10,45, 60,  0,20041210090306
87881132,10,45,300, 20,20041210100101
87881133,10,60, 45, 20,20041210100101
87881134,10,10, 55,-10,20041210101010
87881134,10,20, 55,-10,20041210102020
87881143,10,20, 60,  0,20041210110201
87881143,10,10, 20,  0,20041210111515
第1~8为电话号码
第10~11为基本费
第13~14为长途费
第16~18为附加费
第20~22为优惠费
第24~27为YYYYMMDDHH24MISS格式的日期。
如果我想要把每一个客户的基本费+长途费+附加费+优惠费进行汇总,然后得出日消费总额。当然如果采用Oracle是非常容易的,先把数据用SQL LOADER导入到Oracle数据库中,然后将几个费用的字段按照电话号码进行sum就OK了。当然我要讲的是采用AIX下的awk或者gawk(Linux下,GNU)进行统计,然后导入到Oracle数据库中。我试验过,一般情况下某一个本地网每日的话单都在千万级或者亿级的记录数,在处理速度上采用awk是有优势的。以下就简单的进行介绍。
1)、先写出如下的awk程序:
[zengzc@ZCBILL bill_data]$ cat StatFee.sh
#!/bin/gawk -f
BEGIN \
{
FS=","
}
{
PhoneList[$1]=$1
AllFeesPerPhone=$2+$3+$4+$5
Fee[$1]+=AllFeesPerPhone
};
END \
{
for (Row in PhoneList)
{
 print "Phone Number : "PhoneList[Row]"  All Fees :"Fee[Row]
}
}
2)、chmod +x StatFee.sh
3)、执行:./StatFee.sh Ticket_20041210_11
4)、搞定,得出如下数据:
Phone Number : 87881130  All Fees :105
Phone Number : 87881131  All Fees :115
Phone Number : 87881132  All Fees :375
Phone Number : 87881141  All Fees :140
Phone Number : 87881133  All Fees :135
Phone Number : 87881142  All Fees :260
Phone Number : 87881134  All Fees :140
Phone Number : 87881143  All Fees :550
Phone Number : 87881146  All Fees :70
 
=============================================================
2、用awk实现按照时段进行统计
      炮制电话号码的统计方法。
=============================================================
1)有如下数据(和第一部分是一样的,只是我用awk先把数据进行切分,具体切分方法见后面的附):
[zengzc@ZCBILL bill_data]$ cat Ticket_20041210_11_1
87881141,10,10,120,  0,20041210,09,2920
87881142,10,30,230,-10,20041210,09,2920
87881143,10,30,100,-20,20041210,09,2920
87881143,10,30,110, 10,20041210,09,3825
87881143,10,40, 90,  0,20041210,09,5005
87881146,10,15, 45,  0,20041210,09,2525
87881130,10,15, 80,  0,20041210,09,2525
87881131,10,45, 60,  0,20041210,09,0306
87881132,10,45,300, 20,20041210,10,0101
87881133,10,60, 45, 20,20041210,10,0101
87881134,10,10, 55,-10,20041210,10,1010
87881134,10,20, 55,-10,20041210,10,2020
87881143,10,20, 60,  0,20041210,11,0201
87881143,10,10, 20,  0,20041210,11,1515
2)编写awk脚本,并且存储为:StatFee_Time.sh
[zengzc@ZCBILL bill_data]$ cat StatFee_Time.sh
#!/bin/awk -f 
BEGIN \
{
 FS=","
}
{
 TimeList[$7]=$7
 AllFeesPerPhone=$2+$3+$4+$5
 Fee[$7]+=AllFeesPerPhone
};
END \
{
 for (Row in TimeList)
  print "Time Section : "TimeList[Row]"  All Fees :"Fee[Row]
}
3)、使得脚本StatFee_Time.sh可执行
chmod +x StatFee_Time.sh
4)执行 ./StatFee_Time.sh Ticket_20041210_11_1,OK,得到结果:
[zengzc@ZCBILL bill_data]$ ./StatFee_Time.sh Ticket_20041210_11_1
Time Section : 09  All Fees :1110
Time Section : 10  All Fees :650
Time Section : 11  All Fees :130
附:切分话单中的日期的脚本:
awk -F, '{print $1","$2","$3","$4","$5","substr($6,1,8)","substr($6,9,2)","substr($6,11,4)}' Ticket_20041210_11 >Ticket_20041210_11_1
posted on 2013-01-08 12:37 abin 阅读(1669) 评论(0)  编辑  收藏 所属分类: linux

只有注册用户登录后才能发表评论。


网站导航: