流编辑器sed和gawk
生活随笔
收集整理的這篇文章主要介紹了
流编辑器sed和gawk
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
sed編輯器是一種流編輯器,區(qū)別于交互式vim編輯器,處理數(shù)據(jù)更快。
注意:sed編輯器并不會修改文本文件的數(shù)據(jù)。它只會將修改后的數(shù)據(jù)發(fā)送到STDOUT!
sed 命令的格式如下:sed options script file (sed 選項 腳本 文件)
sed 命令選項:選 項 描 述-e script 在處理輸入時,將 script 中指定的命令添加到已有的命令中-f file 在處理輸入時,將 file 中指定的命令添加到已有的命令中-n 不產(chǎn)生命令輸出,使用 print 命令來完成輸出
1. 在命令行定義編輯器命令echo "This is a test" | sed 's/test/big test/' -- This is a big test s命令會用斜線間指定的第二個文本字符串來替換第一個文本字符串模式。在本例中是 big test 替換了 test sed 's/dog/cat/' data1.txt -- 將data1.txt中的dog替換成cat
2. 在命令行使用多個編輯器命令( -e 選項)sed -e 's/brown/green/; s/dog/cat/' data1.txt -- The quick green fox jumps over the lazy cat.$ sed -e ' -- 不用分號分隔> s/brown/green/> s/fox/elephant/> s/dog/cat/' data1.txt
3. 從文件中讀取編輯器命令( -f 選項)$ cat script1.seds/brown/green/s/fox/elephant/s/dog/cat/$$ sed -f script1.sed data1.txtThe quick green elephant jumps over the lazy cat.The quick green elephant jumps over the lazy cat.The quick green elephant jumps over the lazy cat.The quick green elephant jumps over the lazy cat.$gawk編輯器
gawk 命令的格式如下:gawk options program file
gawk選項:選 項 描 述-F fs 指定行中劃分數(shù)據(jù)字段的字段分隔符-f file 從指定的文件中讀取程序-v var=value 定義gawk程序中的一個變量及其默認值-mf N 指定要處理的數(shù)據(jù)文件中的最大字段數(shù)-mr N 指定數(shù)據(jù)文件中的最大數(shù)據(jù)行數(shù)-W keyword 指定gawk的兼容模式或警告等級
1. 從命令行讀取程序腳本腳本命令需要放入{}中。由于 gawk 命令行假定腳本是單個文本字符串,你還必須將腳本放到單引號中gawk '{print "Hello World!"}' -- 無論輸入什么回車都是Hello World
2.使用數(shù)據(jù)字段變量$0 代表整個文本行;$1 代表文本行中的第1個數(shù)據(jù)字段;$2 代表文本行中的第2個數(shù)據(jù)字段;$n 代表文本行中的第n個數(shù)據(jù)字段。如:$ cat data2.txt -- gawk中默認的字段分隔符是任意的空白字符(例如空格或制表符)One line of test text.Two lines of test text.Three lines of test text.$$ gawk '{print $1}' data2.txtOneTwoThree$gawk -F: '{print $1}' /etc/passwd -- 如果你要讀取采用了其他字段分隔符的文件,可以用 -F 選項指定,-F:并以冒號作為分隔符
3.在程序腳本中使用多個命令echo "My name is Rich" | gawk '{$4="Christine"; print $0}' -- My name is Christine$ gawk '{ -- 也可以逐次輸入> $4="Christine"> print $0}'My name is RichMy name is Christine$
4.從文件中讀取程序( -f 選項指定文件)$ cat script2.gawk{print $1 "'s home directory is " $6}$$ gawk -F: -f script2.gawk /etc/passwdroot's home directory is /rootbin's home directory is /bindaemon's home directory is /sbinadm's home directory is /var/admlp's home directory is /var/spool/lpd[...]Christine's home directory is /home/ChristineSamantha's home directory is /home/SamanthaTimothy's home directory is /home/Timothy$$ cat script3.gawk -- 可以在程序文件中指定多條命令。只要一條命令放一行即可,不需要用分號{text = "'s home directory is "print $1 text $6 -- 注意,gawk程序在引用變量值時并未像shell腳本一樣使用美元符}$$ gawk -F: -f script3.gawk /etc/passwdroot's home directory is /rootbin's home directory is /bindaemon's home directory is /sbinadm's home directory is /var/admlp's home directory is /var/spool/lpd[...]Christine's home directory is /home/ChristineSamantha's home directory is /home/SamanthaTimothy's home directory is /home/Timothy$
5.在處理數(shù)據(jù)前運行腳本(begin)$ cat data3.txtLine 1Line 2Line 3$$ gawk 'BEGIN {print "The data3 File Contents:"}> {print $0}' data3.txtThe data3 File Contents:Line 1Line 2Line 3$
6.在處理數(shù)據(jù)后運行腳本(end)$ gawk 'BEGIN {print "The data3 File Contents:"}> {print $0}> END {print "End of File"}' data3.txt$ cat script4.gawkBEGIN {print "The latest list of users and shells"print " UserID \t Shell"print "-------- \t -------"FS=":"}{print $1 " \t " $7}END {print "This concludes the listing"}$$ gawk -f script4.gawk /etc/passwd
#sed編輯器基礎-------------------------
一、替換選項(s)1.替換標記格式:s/pattern/replacement/flags有4種可用的替換標記:數(shù)字,表明新文本將替換第幾處模式匹配的地方;g ,表明新文本將會替換所有匹配的文本;p ,表明原先行的內(nèi)容要打印出來;w file ,將替換的結果寫到文件中。測試:$ cat data4.txtThis is a test of the test script.This is a different line.$$ sed 's/test/trial/' data4.txtThis is a trial of the test script. -- 默認情況下它只替換每行中出現(xiàn)的第一處testThis is the second trial of the test script.$$ sed 's/test/trial/2' data4.txt -- 替換了第二處的testThis is a test of the trial script.This is the second test of the trial script.$$ sed 's/test/trial/g' data4.txt -- 替換了所有testThis is a trial of the trial script.This is the second trial of the trial script.$$ sed -n 's/test/trial/p' data5.txt -- -n 選項將禁止sed編輯器輸出。但 p 替換標記會輸出修改過的行。將二者配合使用的效果就是只輸出被替換命令修改過的行。This is a trial line.$$ sed 's/test/trial/w test.txt' data5.txt -- 更改過的行將再輸出到文件test.txtThis is a trial line.This is a different line.$$ cat test.txtThis is a trial line.$2.替換字符$ sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd -- 由于正斜線通常用作字符串分隔符,因而如果它出現(xiàn)在了模式文本中的話,必須用反斜線來轉義。麻煩!可以使用下面的方式。$ sed 's!/bin/bash!/bin/csh!' /etc/passwd -- 感嘆號被用作字符串分隔符
二、使用地址1. 數(shù)字方式的行尋址sed '2s/dog/cat/' data1.txt -- 只改變第二行sed '2,3s/dog/cat/' data1.txt -- 改變第2到3行這個區(qū)間的[2,3]sed '2,$s/dog/cat/' data1.txt -- 改變第2到末尾這個區(qū)間[2,$]2. 使用文本模式過濾器$ grep Samantha /etc/passwdSamantha:x:502:502::/home/Samantha:/bin/bash$$ sed '/Samantha/s/bash/csh/' /etc/passwd -- 必須用正斜線將要指定的 pattern 封起來[...]Samantha:x:502:502::/home/Samantha:/bin/csh[...]$3. 命令組合$ sed '2{ -- 單行上執(zhí)行多條命令,可以用花括號將多條命令組合在一起> s/fox/elephant/> s/dog/cat/> }' data1.txtThe quick brown fox jumps over the lazy dog.The quick brown elephant jumps over the lazy cat.The quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.$
三、刪除行(d)$ cat data1.txtThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dog$$ sed 'd' data1.txt -- 刪除所有行$$ sed '3d' data6.txt -- 刪除第三行$$ sed '2,3d' data6.txt -- 刪除2至3行$$ sed '/number 1/d' data6.txt -- 刪除‘number 1’的行$$ sed '/number 1/,/number 3/d' data7.txt -- ‘number 1’開啟刪除,‘number 3’結束刪除。如果后面出現(xiàn)‘number 1’將再次開啟,若未找到‘number 3’結束行將會刪除之后所有$
四、插入和附加文本插入( insert )命令( i )會在指定行前增加一個新行;附加( append )命令( a )會在指定行后增加一個新行。$ echo "Test Line 2" | sed 'i\Test Line 1' -- 當使用插入命令時,文本會出現(xiàn)在數(shù)據(jù)流文本的前面Test Line 1 Test Line 2 $ echo "Test Line 2" | sed 'a\Test Line 1' -- 當使用附加命令時,文本會出現(xiàn)在數(shù)據(jù)流文本的后面Test Line 2Test Line 1$ sed '3i\> This is an inserted line.' data6.txt -- 將一個新行插入到數(shù)據(jù)流第三行前This is line number 1.This is line number 2.This is an inserted line.This is line number 3.This is line number 4.$ sed '3a\> This is an appended line.' data6.txt -- 將一個新行附加到數(shù)據(jù)流中第三行后This is line number 1.This is line number 2.This is line number 3.This is an appended line.This is line number 4.$ sed '$a\> This is a new line of text.' data6.txt -- 將一個新行附加到數(shù)據(jù)流末This is line number 1.This is line number 2.This is line number 3.This is line number 4.This is a new line of text.
五、修改行修改( change )命令允許修改數(shù)據(jù)流中整行文本的內(nèi)容。它跟插入和附加命令的工作機制一樣。$ sed '3c\> This is a changed line of text.' data6.txt -- 修改第三行This is line number 1.This is line number 2.This is a changed line of text.This is line number 4.$ sed '/number 3/c\> This is a changed line of text.' data6.txt -- 修改匹配模式的行This is line number 1.This is line number 2.This is a changed line of text.This is line number 4.$ sed '2,3c\> This is a new line of text.' data6.txt -- 修改區(qū)間行,結果不如所愿。替換了數(shù)據(jù)流中的兩行文本This is line number 1.This is a new line of text.This is line number 4.
六、轉換命令轉換( transform )命令( y )是唯一可以處理單個字符的sed編輯器命令。格式:sed y/inchars/outchars/ 轉換命令會對 inchars 和 outchars 值進行一對一的映射,所以長度要等同。 inchars 中的第一個字符會被轉換為 outchars 中的第一個字符,第二個字符會被轉換成 outchars 中的第二個字符$ echo "This 1 is a test of 1 try." | sed 'y/123/456/' This 4 is a test of 4 try. -- 1轉換成了4$
七、打印p 命令用來打印文本行;等號( = )命令用來打印行號;l (小寫的L)命令用來列出行。1. 打印行$ echo "this is a test" | sed 'p' -- 打印輸出的一行this is a testthis is a test$$ cat data6.txtThis is line number 1.This is line number 2.This is line number 3.This is line number 4.$ sed -n '/number 3/p' data6.txt -- 打印命令最常見的用法是打印包含匹配文本模式的行This is line number 3.$$ sed -n '2,3p' data6.txt -- 打印[2,3]行This is line number 2.This is line number 3.$$ sed -n '/3/{ -- sed編輯器命令會查找包含數(shù)字3的行,然后執(zhí)行兩條命令。首先,腳本用 p 命令來打印出原始行;然后它用 s 命令替換文本,并用 p 標記打印出替換結果> p> s/line/test/p> }' data6.txtThis is line number 3.This is test number 3.$2. 打印行號等號命令會打印行在數(shù)據(jù)流中的當前行號$ cat data1.txtThe quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.$$ sed '=' data1.txt1The quick brown fox jumps over the lazy dog.2The quick brown fox jumps over the lazy dog.3The quick brown fox jumps over the lazy dog.4The quick brown fox jumps over the lazy dog.$$ sed -n '/number 4/{ -- 利用 -n 選項,你就能讓sed編輯器只顯示包含匹配文本模式的行的行號和文本> => p> }' data6.txt4This is line number 4.$3. 列出行列出( list )命令( l )可以打印數(shù)據(jù)流中的文本和不可打印的ASCII字符$ cat data9.txtThis line contains tabs.$$ sed -n 'l' data9.txtThis\tline\tcontains\ttabs.$ -- 制表符的位置會使用 \t 來顯示。行尾的美元符表示換行符。$$ cat data10.txtThis line contains an escape character.$$ sed -n 'l' data10.txtThis line contains an escape character. \a$ -- data10.txt文本文件包含了一個轉義控制碼來產(chǎn)生鈴聲。當用 cat 命令來顯示文本文件時,你看不到轉義控制碼,只能聽到聲音(如果你的音箱打開的話)。但是,利用列出命令,你就能顯示出所使用的轉義控制碼$
八、使用 sed 處理文件1. 寫入文件(write,w)格式:[address]w filename -- filename 參數(shù)指定了數(shù)據(jù)文件的絕對路徑或相對路徑,address指的是外部文件data6.txt$ sed '1,2w test.txt' data6.txt -- 區(qū)間使用。如果你不想讓行顯示到 STDOUT 上,你可以用 sed 命令的 -n 選項This is line number 1.This is line number 2.This is line number 3.This is line number 4.$$ cat test.txtThis is line number 1.This is line number 2.$$ cat data11.txtBlum, R BrowncoatMcGuiness, A AllianceBresnahan, C BrowncoatHarken, C Alliance$$ sed -n '/Browncoat/w Browncoats.txt' data11.txt -- 模式使用。$$ cat Browncoats.txtBlum, R BrowncoatBresnahan, C Browncoat$2. 從文件讀取數(shù)據(jù)(read,r)格式:[address]r filename$ cat data12.txtThis is an added line.This is the second added line.$$ sed '3r data12.txt' data6.txt -- 第三行后This is line number 1.This is line number 2.This is line number 3.This is an added line.This is the second added line.This is line number 4.$$ sed '/number 2/r data12.txt' data6.txtThis is line number 1.This is line number 2.This is an added line.This is the second added line.This is line number 3.This is line number 4.$$ sed '$r data12.txt' data6.txtThis is line number 1.This is line number 2.This is line number 3.This is line number 4.This is an added line.This is the second added line.$$ cat notice.stdWould the following people:LISTplease report to the ship's captain.$$ sed '/LIST/{ -- 在list后添加,并刪除list> r data11.txt> d> }' notice.stdWould the following people:Blum, R BrowncoatMcGuiness, A AllianceBresnahan, C BrowncoatHarken, C Allianceplease report to the ship's captain.$sed深入
#多行命令需要對跨多行的數(shù)據(jù)執(zhí)行特定操作。如一條短語分布在兩行中。三個可用來處理多行文本的特殊命令:N :將數(shù)據(jù)流中的下一行加進來創(chuàng)建一個多行組(multiline group)來處理。D :刪除多行組中的一行。P :打印多行組中的一行。next 命令1. 單行的 next 命令: n 命令會讓sed編輯器移動到文本的下一行。$ cat data1.txtThis is the header line.This is a data line.This is the last line.$ $ sed '/header/{n ; d}' data1.txt -- 找到header會刪除模式匹配成功的下一行This is the header line.This is a data line.This is the last line.$2. 合并文本行:多行版本的 next 命令(用大寫N)會將下一文本行添加到模式空間中已有的文本后,作為一行處理。$ cat data4.txtOn Tuesday, the Linux SystemAdministrator's group meeting will be held.All System Administrators should attend.$$ sed '> s/System Administrator/Desktop User/ -- 將單行命令放前面可以解決最后一行找不到下一行合并的情況> N> s/System\nAdministrator/Desktop\nUser/> ' data4.txtOn Tuesday, the Linux DesktopUser's group meeting will be held.All Desktop Users should attend.$多行刪除命令sed編輯器提供了多行刪除命令 D ,它只刪除模式空間中的第一行。該命令會刪除到換行符(含換行符)為止的所有字符$ sed 'N ; /System\nAdministrator/D' data4.txtAdministrator's group meeting will be held.All System Administrators should attend.$ cat data5.txtThis is the header line.This is a data line.This is the last line.$$ sed '/^$/{N ; /header/D}' data5.txt -- 刪除數(shù)據(jù)流中出現(xiàn)在第一行前的空白行This is the header line.This is a data line.This is the last line.$多行打印命令多行打印命令( P )沿用了同樣的方法。它只打印多行模式空間中的第一行$ cat data3.txtOn Tuesday, the Linux SystemAdministrator's group meeting will be held.All System Administrators should attend.Thank you for your attendance.$$ sed -n 'N ; /System\nAdministrator/P' data3.txtOn Tuesday, the Linux System
#保持空間模式空間(pattern space)是一塊活躍的緩沖區(qū),sed編輯器有另一塊稱作保持空間(hold space)的緩沖區(qū)域。sed編輯器的保持空間命令命 令 描 述h 將模式空間復制到保持空間H 將模式空間附加到保持空間g 將保持空間復制到模式空間G 將保持空間附加到模式空間x 交換模式空間和保持空間的內(nèi)容$ cat data2.txtThis is the header line.This is the first data line.This is the second data line.This is the last line.$$ sed -n '/first/ {h ; p ; n ; p ; g ; p }' data2.txtThis is the first data line.This is the second data line.This is the first data line.$$ sed -n '/first/ {h ; n ; p ; g ; p }' data2.txt -- 合理使用,以相反方向輸出這兩行This is the second data line.This is the first data line.$
#排除命令感嘆號命令( ! )用來排除( negate )命令$ sed -n '/header/!p' data2.txt -- 除了包含單詞header那一行外,文件中其他所有的行都被打印出來了This is the first data line.This is the second data line.This is the last line.$$ sed '$!N; -- 最后一行,不執(zhí)行N命令> s/System\nAdministrator/Desktop\nUser/> s/System Administrator/Desktop User/> ' data4.txtOn Tuesday, the Linux DesktopUser's group meeting will be held.All Desktop Users should attend.$$ cat data2.txtThis is the header line.This is the first data line.This is the second data line.This is the last line.$$ sed -n '{1!G ; h ; $p }' data2.txt -- 倒序輸出(未理解),可以使用tac達到相同效果cat data2.txtThis is the last line.This is the second data line.This is the first data line.This is the header line.$
#改變流sed編輯器會從腳本的頂部開始,一直執(zhí)行到腳本的結尾。sed編輯器提供了一個方法來改變命令腳本的執(zhí)行流程分支( branch )命令 b的格式如下:[ address ]b [ label ]address 參數(shù)決定了哪些行的數(shù)據(jù)會觸發(fā)分支命令。 label 參數(shù)定義了要跳轉到的位置。如果沒有加 label 參數(shù),跳轉命令會跳轉到腳本的結尾。$ cat data2.txtThis is the header line.This is the first data line.This is the second data line.This is the last line.$$ sed '{2,3b ; s/This is/Is this/ ; s/line./test?/}' data2.txt -- 分支命令在數(shù)據(jù)流中的第2行和第3行處跳過了兩個替換命令Is this the header test?This is the first data line.This is the second data line.Is this the last test?$ 要是不想直接跳到腳本的結尾,可以為分支命令定義一個要跳轉到的標簽。標簽以冒號開始,最多可以是7個字符長度。$ sed '{/first/b jump1 ; s/This is the/No jump on/ -- 自定義標簽。標簽允許你跳過地址匹配處的命令,但仍然執(zhí)行腳本中的其他命令> :jump1 > s/This is the/Jump here on/}' data2.txtNo jump on header lineJump here on first data lineNo jump on second data lineNo jump on last line$ $ echo "This, is, a, test, to, remove, commas." | sed -n '{> :start -- 也可以跳轉到腳本中靠前面的標簽上,這樣就達到了循環(huán)的效果> s/,//1p> /,/b start -- 設置了匹配模式,沒有(,)循環(huán)就會終止> }'This is, a, test, to, remove, commas.This is a, test, to, remove, commas.This is a test, to, remove, commas.This is a test to, remove, commas.This is a test to remove, commas.This is a test to remove commas.$ 測試類似于分支命令,測試( test )命令( t )也可以用來改變sed編輯器腳本的執(zhí)行流程格式:[ address ]t [ label ] $ sed '{> s/first/matched/> t -- first改行不再執(zhí)行> s/This is the/No match on/> }' data2.txtNo match on header lineThis is the matched data lineNo match on second data lineNo match on last line$ $ echo "This, is, a, test, to, remove, commas. " | sed -n '{> :start> s/,//1p> t start -- 當無需替換時,測試命令不會跳轉而是繼續(xù)執(zhí)行剩下的腳本> }'This is, a, test, to, remove, commas.This is a, test, to, remove, commas.This is a test, to, remove, commas.This is a test to, remove, commas.This is a test to remove, commas.This is a test to remove commas.$
#模式替代& 符號不管模式匹配的是什么樣的文本,你都可以在替代模式中使用 & 符號來使用這段文本$ echo "The cat sleeps in his hat." | sed 's/.at/"&"/g'The "cat" sleeps in his "hat".替代單獨的單詞sed編輯器用圓括號來定義替換模式中的子模式。替代字符由反斜線和數(shù)字組成,第一個子模式分配字符 \1 ,給第二個子模式分配字符 \2 ,依此類推。$ echo "The System Administrator manual" | sed '> s/\(System\) Administrator/\1 User/' -- \1 來提取第一個匹配的子模式The System User manual $ echo "1234567" | sed '{ -- 大數(shù)字中插入逗號> :start> s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/> t start> }'1,234,567
#腳本中使用sed使用包裝腳本$ cat sw_cs.shsed -n '{ 1!G ; h ; $p }' $1$$ sh sw_cs.sh data2.txtThis is the last line.This is the second data line.This is the first data line.This is the header line.重定向 sed 的輸出$ cat fact.shfactorial=1counter=1number=$1#while [ $counter -le $number ]dofactorial=$[ $factorial * $counter ]counter=$[ $counter + 1 ]done#result=$(echo $factorial | sed '{:starts/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/t start}')#echo "The result is $result"#$$ sh fact.sh 20The result is 2,432,902,008,176,640,000$
#創(chuàng)建 sed 實用工具1.加倍行間距$ sed 'G' data2.txtThis is the header line.This is the first data line.This is the second data line.This is the last line.$$ sed '$!G' data2.txtThis is the header line.This is the first data line.This is the second data line.This is the last line. -- 最后一行跳過G$2.對可能含有空白行的文件加倍行間距$ cat data6.txtThis is line one.This is line two.This is line three.This is line four.$ $ sed '/^$/d ; $!G' data6.txtThis is line one.This is line two.This is line three.This is line four.$ 3.給文件中的行編號$ sed '=' data2.txt | sed 'N; s/\n/ /'1 This is the header line.2 This is the first data line.3 This is the second data line.4 This is the last line.4.打印末尾行(打印末尾10行)$ cat data7.txtThis is line 1.This is line 2.This is line 3.This is line 4.This is line 5.This is line 6.This is line 7.This is line 8.This is line 9.This is line 10.This is line 11.This is line 12.This is line 13.This is line 14.This is line 15.$$ sed '{> :start> $q ; N ; 11,$D> b start> }' data7.txtThis is line 6.This is line 7.This is line 8.This is line 9.This is line 10.This is line 11.This is line 12.This is line 13.This is line 14.This is line 15.$5.刪除行刪除連續(xù)的空白行:$ sed '/./,/^$/!d' data8.txt刪除開頭的空白行:$ sed '/./,$!d' data9.txt刪除結尾的空白行:$ sed '{:start/ ^\n*$/{$d; N; b start }}'6.刪除 HTML 標簽$ sed 's/<[^>]*>//g ; /^$/d' data11.txtgawk深入
#使用變量一、內(nèi)建變量1. 字段和記錄分隔符變量gawk數(shù)據(jù)字段和記錄變量變 量 描 述FIELDWIDTHS 由空格分隔的一列數(shù)字,定義了每個數(shù)據(jù)字段確切寬度FS 輸入字段分隔符RS 輸入記錄分隔符OFS 輸出字段分隔符ORS 輸出記錄分隔符FS與OPS的使用$ cat data1data11,data12,data13,data14,data15data21,data22,data23,data24,data25data31,data32,data33,data34,data35$ gawk 'BEGIN{FS=","} {print $1,$2,$3}' data1 -- 默認情況下,gawk將 OFS 設成一個空格data11 data12 data13data21 data22 data23data31 data32 data33$ gawk 'BEGIN{FS=","; OFS="-"} {print $1,$2,$3}' data1 -- 修改輸出分隔符值data11-data12-data13data21-data22-data23data31-data32-data33FIELDWIDTHS 變量定義了四個字段,根據(jù)已定義好的字段長度來分割$ cat data1b1005.3247596.37115-2.349194.0005810.1298100.1$ gawk 'BEGIN{FIELDWIDTHS="3 5 2 5"}{print $1,$2,$3,$4}' data1b100 5.324 75 96.37115 -2.34 91 94.00058 10.12 98 100.1RS與ORS的使用:默認情況下,gawk將 RS 和 ORS 設為換行符$ cat data2Riley Mullen123 Main StreetChicago, IL 60601(312)555-1234Frank Williams456 Oak StreetIndianapolis, IN 46201(317)555-9876Haley Snell4231 Elm StreetDetroit, MI 48201(313)555-4938$ gawk 'BEGIN{FS="\n"; RS=""} {print $1,$4}' data2 -- 現(xiàn)在gawk把文件中的每行都當成一個字段,把空白行當作記錄分隔符Riley Mullen (312)555-1234Frank Williams (317)555-9876Haley Snell (313)555-49382. 數(shù)據(jù)變量更多的gawk內(nèi)建變量變 量 描 述ARGC 當前命令行參數(shù)個數(shù)ARGIND 當前文件在 ARGV 中的位置ARGV 包含命令行參數(shù)的數(shù)組CONVFMT 數(shù)字的轉換格式(參見 printf 語句),默認值為 %.6 gENVIRON 當前shell環(huán)境變量及其值組成的關聯(lián)數(shù)組ERRNO 當讀取或關閉輸入文件發(fā)生錯誤時的系統(tǒng)錯誤號FILENAME 用作gawk輸入數(shù)據(jù)的數(shù)據(jù)文件的文件名FNR 當前數(shù)據(jù)文件中的數(shù)據(jù)行數(shù)IGNORECASE 設成非零值時,忽略 gawk 命令中出現(xiàn)的字符串的字符大小寫NF 數(shù)據(jù)文件中的字段總數(shù)NR 已處理的輸入記錄數(shù)OFMT 數(shù)字的輸出格式,默認值為 %.6 gRLENGTH 由 match 函數(shù)所匹配的子字符串的長度RSTART 由 match 函數(shù)所匹配的子字符串的起始位置ARGC與ARGV$ gawk 'BEGIN{print ARGC,ARGV[1]}' data1 -- ARGC 變量表明命令行上有兩個參數(shù)。 ARGV 數(shù)組從索引 0 開始。ENVIRON 變量,使用關聯(lián)數(shù)組來提取shell環(huán)境變量$ gawk '> BEGIN{> print ENVIRON["HOME"]> print ENVIRON["PATH"]> }'/home/rich/usr/local/bin:/bin:/usr/bin:/usr/X11R6/binNF 變量可以讓你在不知道具體位置的情況下指定記錄中的最后一個數(shù)據(jù)字段$ gawk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd -- rich:/bin/bashtesty:/bin/cshmark:/bin/bashdan:/bin/bashmike:/bin/bashtest:/bin/bashFNR 和 NR 變量雖然類似,但又略有不同。$ gawk '> BEGIN {FS=","}> {print $1,"FNR="FNR,"NR="NR}> END{print "There were",NR,"records processed"}' data1 data1 data11 FNR=1 NR=1data21 FNR=2 NR=2data31 FNR=3 NR=3data11 FNR=1 NR=4 -- FNR 變量的值在 gawk 處理第二個數(shù)據(jù)文件時被重置了,而 NR 變量則在處理第二個數(shù)據(jù)文件時繼續(xù)計數(shù)。data21 FNR=2 NR=5data31 FNR=3 NR=6There were 6 records processed2 data1二、自定義變量gawk自定義變量名可以是任意數(shù)目的字母、數(shù)字和下劃線,但不能以數(shù)字開頭。注意: gawk 變量名區(qū)分大小寫!1. 在腳本中給變量賦值(值可以是數(shù)字、文本,賦值支持數(shù)學算式)$ gawk '> BEGIN{> testing="This is a test"> print testing> testing=45> print testing> }'This is a test45 $ gawk 'BEGIN{x=4; x= x * 2 + 3; print x}'11 2. 在命令行上給變量賦值$ cat script1BEGIN{FS=","}{print $n}$ gawk -f script1 n=2 data1 -- 顯示了文件的第二個數(shù)據(jù)字段data12data22data32用 -v 命令行參數(shù),它允許你在 BEGIN 代碼之前設定變量,否則設定的變量值在begin部分不可用。-v 命令行參數(shù)必須放在腳本代碼之前。$ gawk -v n=3 -f script2 data1The starting value is 3data13data23data33
#處理數(shù)組定義數(shù)組變量格式:var[index] = element 其中 var 是變量名,index 是關聯(lián)數(shù)組的索引值,element 是數(shù)據(jù)元素值$ gawk 'BEGIN{> capital["Illinois"] = "Springfield"> print capital["Illinois"]> }'Springfield$$ gawk 'BEGIN{> var[1] = 34> var[2] = 3> total = var[1] + var[2]> print total> }'37 遍歷數(shù)組變量gwak遍歷格式:for (var in array){statements}變量中存儲的是索引值而不是數(shù)組元素值$ gawk 'BEGIN{> var["a"] = 1> var["g"] = 2> var["m"] = 3> var["u"] = 4> for (test in var)> {> print "Index:",test," - Value:",var[test]> }> }'Index: u - Value: 4Index: m - Value: 3Index: a - Value: 1Index: g - Value: 2 刪除數(shù)組變量格式:delete array[index]刪除命令會從數(shù)組中刪除關聯(lián)索引值和相關的數(shù)據(jù)元素值$ gawk 'BEGIN{> var["a"] = 1> var["g"] = 2> for (test in var)> {> print "Index:",test," - Value:",var[test]> }> delete var["g"]> print "---"> for (test in var)> print "Index:",test," - Value:",var[test]> }'Index: a - Value: 1Index: g - Value: 2---Index: a - Value: 1
#使用模式正則表達式正則表達式必須出現(xiàn)在它要控制的程序腳本的左花括號前$ gawk 'BEGIN{FS=","} /11/{print $1}' data1data11匹配操作符匹配操作符是波浪線( ~ ),允許將正則表達式限定在記錄中的特定數(shù)據(jù)字段$ gawk –F: '$1 !~ /rich/{print $1,$NF}' /etc/passwd -- gawk程序腳本會打印/etc/passwd文件中與用戶ID rich 不匹配的用戶ID和登錄shellroot /bin/bashdaemon /bin/shbin /bin/shsys /bin/sh$ gawk -F: '$1 ~ /rich/{print $1,$NF}' /etc/passwdrich /bin/bash$ gawk 'BEGIN{FS=","} $2 ~ /^data2/{print $0}' data1data21,data22,data23,data24,data25數(shù)學表達式可以使用任何常見的數(shù)學比較表達式。x == y :值x等于y。x <= y :值x小于等于y。x < y :值x小于y。x >= y :值x大于等于y。x > y :值x大于y。$ gawk -F: '$4 == 0{print $1}' /etc/passwd -- 顯示所有屬于root用戶組(組ID為 0 )的系統(tǒng)用戶rootsyncshutdownhaltoperator也可以對文本數(shù)據(jù)使用表達式,跟正則表達式不同,表達式必須完全匹配$ gawk -F, '$1 == "data"{print $1}' data1$$ gawk -F, '$1 == "data11"{print $1}' data1data11
#結構命令if語句gawk編程語言支持標準的 if-then-else 格式的 if 語句。你必須為 if 語句定義一個求值的條件,并將其用圓括號括起來格式:if (condition) statement1$ cat data4105135034$ gawk '{if ($1 > 20) print $1}' data45034$ gawk '{> if ($1 > 20)> { -- 執(zhí)行多條語句,就必須用花括號將它們括起來> x = $1 * 2> print x> }> }' data410068gawk 的 if 語句也支持 else 子句,允許在 if 語句條件不成立的情況下執(zhí)行一條或多條語句$ gawk '{> if ($1 > 20)> {> x = $1 * 2> print x> } else> {> x = $1 / 2> print x> }}' data452.56.510068while語句while 循環(huán)允許遍歷一組數(shù)據(jù),并檢查迭代的結束條件格式:while (condition){statements}$ cat data5130 120 135160 113 140145 170 215$ gawk '{> total = 0> i = 1> while (i < 4)> {> total += $i> i++> }> avg = total / 3> print "Average:",avg> }' data5Average: 128.333Average: 137.667Average: 176.667gawk編程語言支持在 while 循環(huán)中使用 break 語句和 continue 語句,允許你從循環(huán)中跳出$ gawk '{> total = 0> i = 1> while (i < 4)> {> total += $i> if (i == 2)> break> i++> }> avg = total / 2> print "The average of the first two data elements is:",avg> }' data5The average of the first two data elements is: 125The average of the first two data elements is: 136.5The average of the first two data elements is: 157.5do—while語句do-while 語句類似于 while 語句,但會在檢查條件語句之前執(zhí)行命令格式:do{statements} while (condition)$ gawk '{> total = 0> i = 1> do> {> total += $i> i++> } while (total < 150)> print total }' data5250160315for語句gawk編程語言支持C風格的 for 循環(huán)格式:for( variable assignment; condition; iteration process)$ gawk '{> total = 0> for (i = 1; i < 4; i++)> {> total += $i> }> avg = total / 3> print "Average:",avg> }' data5Average: 128.333Average: 137.667Average: 176.667
#格式化打印格式:printf "format string", var1, var2 . . . format string 是格式化輸出的關鍵它會用文本元素和格式化指定符來具體指定如何呈現(xiàn)格式化輸出。格式化指定符是一種特殊的代碼,會指明顯示什么類型的變量以及如何顯示。gawk程序會將每個格式化指定符作為占位符,供命令中的變量使用。第一個格式化指定符對應列出的第一個變量,第二個對應第二個變量,依此類推格式化指定符格式:%[modifier]control-letter -- 其中 control-letter 是一個單字符代碼,用于指明顯示什么類型的數(shù)據(jù)格式化指定符的控制字母控制字母 描 述c 將一個數(shù)作為ASCII字符顯示d 顯示一個整數(shù)值i 顯示一個整數(shù)值(跟d一樣)e 用科學計數(shù)法顯示一個數(shù)f 顯示一個浮點值g 用科學計數(shù)法或浮點數(shù)顯示(選擇較短的格式)o 顯示一個八進制值s 顯示一個文本字符串x 顯示一個十六進制值X 顯示一個十六進制值,但用大寫字母A~F 科學計數(shù)法顯示一個數(shù)$ gawk 'BEGIN{> x = 10 * 100> printf "The answer is: %e\n", x> }'The answer is: 1.000000e+03除了控制字母外,還有3種修飾符可以用來進一步控制輸出:width :指定了輸出字段最小寬度的數(shù)字值。如果輸出短于這個值, printf 會將文本右對齊,并用空格進行填充。如果輸出比指定的寬度還要長,則按照實際的長度輸出。prec :這是一個數(shù)字值,指定了浮點數(shù)中小數(shù)點后面位數(shù),或者文本字符串中顯示的最大字符數(shù)。- (減號):指明在向格式化空間中放入數(shù)據(jù)時采用左對齊而不是右對齊。在使用 printf 語句時,你可以完全控制輸出樣式通過添加一個值為 16 的修飾符,我們強制第一個字符串的輸出寬度為16個字符。默認情況下,printf 命令使用右對齊來將數(shù)據(jù)放到格式化空間中。要改成左對齊,只需給修飾符加一個減號即可 $ gawk 'BEGIN{FS="\n"; RS=""} {printf "%-16s %s\n", $1, $4}' data2Riley Mullen (312)555-1234Frank Williams (317)555-9876Haley Snell (313)555-4938
#內(nèi)建函數(shù)數(shù)學函數(shù)gawk數(shù)學函數(shù)函 數(shù) 描 述atan2(x, y) x/y的反正切,x和y以弧度為單位cos(x) x的余弦,x以弧度為單位exp(x) x的指數(shù)函數(shù)int(x) x的整數(shù)部分,取靠近零一側的值log(x) x的自然對數(shù)rand( ) 比0大比1小的隨機浮點值sin(x) x的正弦,x以弧度為單位sqrt(x) x的平方根srand(x) 為計算隨機數(shù)指定一個種子值gawk還支持一些按位操作數(shù)據(jù)的函數(shù)。and(v1, v2) :執(zhí)行值 v1 和 v2 的按位與運算。compl(val) :執(zhí)行 val 的補運算。lshift(val, count) :將值 val 左移 count 位。or(v1, v2) :執(zhí)行值 v1 和 v2 的按位或運算。rshift(val, count) :將值 val 右移 count 位。xor(v1, v2) :執(zhí)行值 v1 和 v2 的按位異或運算。字符串函數(shù)gawk字符串函數(shù)函 數(shù) 描 述asort(s [,d]) 將數(shù)組s按數(shù)據(jù)元素值排序。索引值會被替換成表示新的排序順序的連續(xù)數(shù)字。另外,如果指定了d,則排序后的數(shù)組會存儲在數(shù)組d中asorti(s [,d]) 將數(shù)組s按索引值排序。生成的數(shù)組會將索引值作為數(shù)據(jù)元素值,用連續(xù)數(shù)字索引來表明排序順序。另外如果指定了d,排序后的數(shù)組會存儲在數(shù)組d中gensub(r, s, h [, t]) 查找變量$0或目標字符串t(如果提供了的話)來匹配正則表達式r。如果h是一個以g或G開頭的字符串,就用s替換掉匹配的文本。如果h是一個數(shù)字,它表示要替換掉第h處r匹配的地方gsub(r, s [,t]) 查找變量$0或目標字符串t(如果提供了的話)來匹配正則表達式r。如果找到了,就全部替換成字符串sindex(s, t) 返回字符串t在字符串s中的索引值,如果沒找到的話返回 0length([s]) 返回字符串s的長度;如果沒有指定的話,返回$0的長度match(s, r [,a]) 返回字符串s中正則表達式r出現(xiàn)位置的索引。如果指定了數(shù)組a,它會存儲s中匹配正則表達式的那部分split(s, a [,r]) 將s用 FS 字符或正則表達式r(如果指定了的話)分開放到數(shù)組a中。返回字段的總數(shù)sprintf(format,variables) 用提供的format和variables返回一個類似于printf輸出的字符串sub(r, s [,t]) 在變量$0或目標字符串t中查找正則表達式r的匹配。如果找到了,就用字符串s替換掉第一處匹配substr(s, i [,n]) 返回s中從索引值i開始的n個字符組成的子字符串。如果未提供n,則返回s剩下的部分tolower(s) 將s中的所有字符轉換成小寫toupper(s) 將s中的所有字符轉換成大寫轉換大寫,返回長度$ gawk 'BEGIN{x = "testing"; print toupper(x); print length(x) }'TESTING7 排序$ gawk 'BEGIN{> var["a"] = 1> var["g"] = 2> var["m"] = 3> var["u"] = 4> asort(var, test)> for (i in test)> print "Index:",i," - value:",test[i]> }'Index: 4 - value: 4Index: 1 - value: 1Index: 2 - value: 2Index: 3 - value: 3 時間函數(shù)gawk的時間函數(shù)函 數(shù) 描 述mktime(datespec) 將一個按YYYY MM DD HH MM SS [DST]格式指定的日期轉換成時間戳值 ①strftime(format[,timestamp]) 將當前時間的時間戳或timestamp(如果提供了的話)轉化格式化日期(采用shell函數(shù)date()的格式) systime( ) 返回當前時間的時間戳例如:$ gawk 'BEGIN{> date = systime()> day = strftime("%A, %B %d, %Y", date)> print day> }'Friday, December 26, 2014
#自定義函數(shù)定義函數(shù)格式:function name([variables]){statements}使用自定義函數(shù)在定義函數(shù)時,它必須出現(xiàn)在所有代碼塊之前(包括 BEGIN 代碼塊),有助于將函數(shù)代碼與gawk程序的其他部分分開$ gawk '> function myprint()> {> printf "%-16s - %s\n", $1, $4> }> BEGIN{FS="\n"; RS=""}> {> myprint()> }' data2Riley Mullen - (312)555-1234Frank Williams - (317)555-9876Haley Snell - (313)555-4938創(chuàng)建函數(shù)庫$ cat funclibfunction myprint(){printf "%-16s - %s\n", $1, $4}function myrand(limit){return int(limit * rand())}function printthird(){print $3}$ cat script4BEGIN{ FS="\n"; RS=""}{myprint()}$ gawk -f funclib -f script4 data2Riley Mullen - (312)555-1234Frank Williams - (317)555-9876Haley Snell - (313)555-4938
#實例計算保齡球錦標賽成績$ cat scores.txtRich Blum,team1,100,115,95Barbara Blum,team1,110,115,100Christine Bresnahan,team2,120,115,118Tim Bresnahan,team2,125,112,116$ cat bowling.shfor team in $(gawk –F, '{print $2}' scores.txt | uniq)dogawk –v team=$team 'BEGIN{FS=","; total=0}{if ($2==team){total += $3 + $4 + $5;}}END {avg = total / 6;print "Total for", team, "is", total, ",the average is",avg}' scores.txtdone$ sh bowling.shTotal for team1 is 635, the average is 105.833Total for team2 is 706, the average is 117.667
?
轉載于:https://www.cnblogs.com/TianMu/p/11199371.html
總結
以上是生活随笔為你收集整理的流编辑器sed和gawk的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: markdown编辑器实现代码高亮
- 下一篇: 2009年诺基亚中国开发伙伴峰会召开