歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> 總結Linux中用於文本處理的awk、sed、grep命令用法

總結Linux中用於文本處理的awk、sed、grep命令用法

日期:2017/3/1 17:30:25   编辑:Linux技術

awk
基礎概念
Awk把文件(或其他方式的輸入流, 如重定向輸入)看作一個記錄集, 把每一行看作一條記錄, 把每一行中以空格(或\t,或用戶自己指定的分隔符)分割的字符串看作一個字段. 這似乎把文件記錄看成數據庫. 但是, awk仍然以行為單位逐行處理. 本例子以下面的文件(命名為s.txt)內容做演示:

復制代碼代碼如下:
zhangsan 1977 male computer 83
lisi 1989 male math 99
wanglijiang 1990 female chinese 78
xuliang 1977 male economic 89
xuxin 1986 female english 99
wangxuebing 1978 male math 89
lichang 1989 male math 99
wanglijiang 1990 female chinese 78
zhangsansan 1977 male computer 83
langxuebing 1978 male math 89
lisibao 1989 male math 99
xiaobao 1990 female chinese 78

一行中的5個字段分辨表示姓名, 出生年, 性別,科目,分數, 是一個很傳統很典型的報表文件.
Awk基本語法: awk ‘pattern1 {command1;command 2…; command 3}pattern2 { command …}’
pattern表示用來過濾記錄的模式, 可是是正則表達式, 關系運算表達式, 也可以什麼也沒有(表示選中所有記錄);
每個pattern選中的行記錄會被花括號括起來的命令command操作一遍, command之間用;分割. 花括號裡面可以什麼也沒有, 則默認為print輸出整行記錄. Comamnd可以是輸出, 可以是算術運算, 邏輯運算, 循環控制等等.
先看幾個例子, 以建立對awk的命令直觀的了解.

復制代碼代碼如下:
awk ‘/1990/’ s.txt #//直接輸出1990年出生的同學;
awk ‘/chinese/{print “語文”; print “語文”}’s.txt #// 對chinese的課程的行輸出兩行”語文 +”;
awk ‘20>1{print “Yes”}’ s.txt #//因為20>0,所以每行輸出Yes;
awk 'BEGIN{print "Result of the quiz:\n"}{print}END{print"---------------------------"}' s.txt

結果:
本例有3個花括號,分別對應3個模式, BEGIN和END是特殊模式,分別作用在記錄開始前和記錄結束後.
變量: 上面說到command可以是算術運算, 所及運算等, 則既然有運算, 就有常量變量, awk可以自定義變量(不需要提前聲明, 但最好在BEGIN裡面給它初始化). Awk也維護了一組程序變量:

變量

說明

$0

當前記錄;

$1, $2, … $n

當前記錄的字段

FILENAME

當前的文件名

FS

輸入字段的分隔符, 可通過-F修改. 如: 先通過sed把空格替換為|,然後管道輸送給awk:
sed 's/ /|/g' s.txt | awk -F '|' '/chinese/{print FILENAME, $1, $5}'

NF

當前記錄的字段數

NR

當前記錄編號

OFS

輸出字段分隔符

ORS

輸出記錄分隔符

RS

記錄分隔符, 默認為換行符


給一些例子來說明這些變量的用法:

復制代碼代碼如下:
awk ‘$4==”chinese”{print NR, $1, $4, $5}’ s.txt #//第四個字段科目為chinese的記錄編號, 學生姓名, 科目和成績.
awk ‘$2~/1990/{print $1}’ s.txt #//找出1990年出生的學生姓名, ~表示匹配正則表達式
awk ‘$2!~/1990/{print $1}’ s.txt #//找出不是1990年出生的學生姓名, !~表示不匹配正則表達式
awk ‘$2>”1985”{print $1, $2}’ s.txt #//找出大於1985年出生的學生姓名,年齡
awk ‘END{print “total: ” NR ”\n----------------” }’ s.txt
awk ‘BEGIN{goodChinese=0; goodMath=0}($4==”chinese”||$5>90){goodChinese++}END{print“”}

sed
sed '2,5d' file 顯示文件file,除去2-5行,但行數超過文件實際行數時不會報錯。
sed '/10[1-4]/d' file 顯示文件file,除去包含101-104的行。
sed '2,$d' file 顯示文件,只顯示第一行。sed '2,$!d' file則只顯示除第一行外的其它行。
sed '/^ *$/d file 刪除文件中的空行。
sed -n '/10[1-4]/p' file
只顯示文件file中包含101-104的行。(n和p必須同時使用,否則只有p時顯示全部文件並多顯示一次找到的行)
sed -n '5p' file 只顯示文件的第5行
sed 's/moding/moden/g' file 將moding替換為moden
sed -n 's/^west/north/p' file 將west開頭的行替換為north並顯示出來。
sed 's/[0-9][0-9][0-9]$/&.5/' file 將file文件中以3個數字結尾的行替換為原數字加".5",&代表搜索到的字符串。
sed 's/moding/\1en/g file 將mod做為模式1封裝在括號裡,然後替換。
sed 's/...$//' file 刪除每一行的最後三個字符。
sed 's/^...//' file 刪除每一行的頭三個字符。
sed 's#moding#moden#g' file將moding替換為moden,s後面的#代表搜索串和替換串之間的分界符。
sed -n '/101/,/105/p' file 顯示從101的匹配行到105的匹配行。如果只找到101的匹配行,則從101的匹配行到文件末。
sed -n '2,/999/p' file 顯示從第2行到匹配行。
sed'/101/,/105/s/$/ 20050119/' file將從101的匹配行到105的匹配行的行末增加" 20050119"內容。
sed -e '1,3d' -e 's/moding/moden/g'file 先刪除文件的1-3行,再進行替換。
sed -e '/^#/!d' file 顯示文件以#開頭的行。
sed '/101/r newfile' file 在每個匹配行增加文件newfile的內容
sed '/101/w newfile' file 把匹配行寫入newfile。
sed '/101/a new text' file 在匹配行後增加一新行。
sed '/101/i' new text' file 在匹配行前增加一新行。
sed '/101/c new text' file 用新行替換匹配行。
sed 'y/abcd/ABCD/' file 將a、b、c、d分別替換為ABCD。
sed '5q' file 顯示到第5行時退出。
sed '/101/{ n; s/moding/moden/g; }' file在文件中找到匹配行的後一行(n)再進行替換。
sed '/101/{ s/moding/moden/g; q; }' file在文件中找到第一個匹配行後進行替換後再退出。
sed -e '/101/{ h; d; }' -e '/104/{ G; }'file 在文件中找到與101匹配行後先存在一個緩存中,再放在與104匹配行後。
sed -e '/101/{ h; d; }' -e '/104/{ g; }'file 在文件中找到與101匹配行後先存在一個緩存中,再替代104的匹配行。
sed -e '/101/h' -e '$G' file 將最後一個匹配行放在文件末。
sed -e '/101/h' -e '$g' file 將最後一個匹配行替換文件末行。
sed -e '/101/h' -e '/104/x' file 在文件中找到與101匹配行後先存在一個緩存中,再與104的匹配行進行互換。
echo –ltr 1.txt | sed‘s/^.* //’ 找出文件名

grep
常用的grep選項
-c 只輸出匹配行的計數。// 這條有時候很有用, 不需要再 | wc -l
-i 不區分大小寫(只適用於單字符)。
-h 查詢多文件時不顯示文件名。
-l 查詢多文件時只輸出包含匹配字符的文件名。
-n 顯示匹配行及行號。
-s 不顯示不存在或無匹配文本的錯誤信息。
-v 顯示不包含匹配文本的所有行。
例子

復制代碼代碼如下:grep -v "Sort" tab2 顯示不包含匹配文本的所有行

復制代碼代碼如下:grep -n "Sort" tab2 顯示匹配行及行號

復制代碼代碼如下:grep -c "Sort" tab2 只輸出匹配行的計數
精確匹配:
復制代碼代碼如下:grep "01">" tab2

復制代碼代碼如下:grep -in "code" tab2 忽略大小寫
多次過濾

復制代碼代碼如下:grep -in "code" tab2 | grep "02"
補充說明,grep 家族還包括fgrep和egrep。fgrep是fix grep, 允許查找字符串而不是一個模式,運算速度快,適合於從大量數據中進行檢索;egrep是擴展grep,支持基本及擴展的正則表達式,可用()及|等,但不支持q模式范圍的應用及與之相對應的一些更加規范的模式。

復制代碼代碼如下:echo aAA123bbb |egrep '[0-9]*'

復制代碼代碼如下:echo AAA123bbb | egrep -i '^a'

Copyright © Linux教程網 All Rights Reserved