準(zhǔn)備
grep、sed、awk號(hào)稱"linux三劍客",使用頻繁,功能強(qiáng)大,本文通過一個(gè)實(shí)例演示下基本用法。首先準(zhǔn)備一個(gè)文本文件,命名為text.txt,寫入文件內(nèi)容:
cat > test.txt <<EOF
1 province 省份 青海省
2 domain 域名或者ip tianfengyinlou.cn
3 subject_no 主體備案號(hào) 青ICP備11000289號(hào)
4 addr 注冊(cè)地址 青海省西寧市城中區(qū)南關(guān)街138號(hào)
5 check_time 備案時(shí)間, 時(shí)間對(duì)象 2011-06-23 16:38:00
6 update_time 更新時(shí)間, 毫秒級(jí)時(shí)間戳 1607414120745
7 site_no 網(wǎng)站備案/許可證號(hào) 青ICP備11000289號(hào)-2
8 site_url 站點(diǎn)/網(wǎng)站首頁(yè)網(wǎng)址 www.tianfengyinlou.cn
9 comp_name 主辦單位名稱(公司名稱) 西寧天豐銀樓金銀珠寶有限公司
EOF
grep
首先,最簡(jiǎn)單的是grep。經(jīng)常用來過濾查看日志。對(duì)于grep需要知道如下幾個(gè)常用的命令選項(xiàng):
-n:
額外輸出行號(hào)。例如過濾出每一行包含"青"的記錄:
grep -n "青" text.txt
-v:
排除匹配的行。例如排除包含"青"的行記錄:
grep -nv "青" text.txt
grep -n -v "青" text.txt
-E:
支持?jǐn)U展正則匹配。grep的時(shí)候,我們可以按照正則表達(dá)式來進(jìn)行匹配,但在需要擴(kuò)展正則匹配時(shí),要通過-E指定才能生效。常見的或操作,比如篩選包含"青海省"或者"青ICP"的行記錄,不指定-E是無(wú)法獲得想要的結(jié)果的。
grep -E "青ICP|青海省" text.txt
-l
只輸出有匹配行的文件名。有時(shí)候,我們并不需要輸出匹配的行記錄,僅僅只是需要知道匹配到了行記錄的文件名:
grep -l "省" text.txt
-r
遞歸匹配目錄中的文件內(nèi)容。有時(shí)候,在一個(gè)目錄中我們并不知道哪個(gè)文件內(nèi)容包含我們想要的結(jié)果,此時(shí),可以查找整個(gè)目錄,輸出匹配的文件名以及行記錄:
grep -r 省 ./mayanan/
結(jié)合-l參數(shù)就可以知道一個(gè)目錄中有哪些文件包含了匹配項(xiàng):
grep -lr 省abc mayanan/
-A
通過-A(after)指定輸出匹配行后的額外行數(shù)。例如,想要額外輸出包含"青"的行記錄后一行,可以指定-A1:
grep -A1 青 text.txt
-B
通過-B(before)指定輸出匹配行前的額外行數(shù)。例如,想要額外輸出包含"青"的行記錄前一行,可以指定-B1:
grep -B1 青 text.txt
-C
通過-C指定輸出匹配行前后的額外行數(shù)。例如,想要額外輸出包含"青"的行記錄前后各一行,可以指定-C1:
grep -C1 青 text.txt
sed
查找
sed的各項(xiàng)操作需要指定一個(gè)特定的動(dòng)作。查找需要指定一個(gè)動(dòng)作為p(print),例如,打印出第三行的記錄,需要指定行號(hào)加動(dòng)作3p:
sed -n 3p text.txt
這里必須指定一個(gè)選項(xiàng)-n。因?yàn)閟ed的默認(rèn)行為是遍歷文本文件的每一行并輸出每一行,假如不帶-n選項(xiàng),第三行會(huì)輸出兩次=默認(rèn)輸出一次+命令行指定輸出一次:
sed 3p text.txt
所以-n的作用是取消sed的默認(rèn)輸出行為, 一般都只與p組合使用。利用sed的默認(rèn)輸出行為,我們可以模擬復(fù)制每一行的操作,有時(shí)候在特定場(chǎng)景下非常有用:
sed p text.txt
sed不僅可以輸出指定的某一行,還可以按行號(hào)范圍進(jìn)行輸出,例如輸出1-5行:
sed -n 1,5p text.txt
sed還可以按照正則匹配來輸出特定的行。格式為/xx/p, 例如,查找包含"青海省"的行記錄:
sed -n "/青海省/p" text.txt
查找包含數(shù)字0到6的行記錄:
sed -n "/[0-6]/p" text.txt
查找以0結(jié)尾的行記錄:
sed -n '/0$/p' text.txt
如果想要支持?jǐn)U展正則匹配,需要通過-r來指定,例如查找每一行包含"青海省"或者"青"的記錄:
sed -nr '/青海省|青/p' text.txt
sed正則匹配也支持按范圍輸出,格式為/xx/,/xx/p。例如查找包含"domain"的行到包含"addr"的行記錄:
sed -n '/addr/,/site_no/p' text.txt
刪除
# 刪除第3行
sed 3d text.txt
# 刪除包含青的行
sed '/青/d' text.txt
# 刪除空行和注釋行
sed -r '/^$|#/d' text.txt
增加
sed的增加動(dòng)作有三種:
- i:在指定行的上方增加一行
- a: 在指定行的下方增加一行
- c: 在指定行的地方增加一行,原有行會(huì)被覆蓋
上述三種增加行為示例為:
注意:示例的增加行為在mac上會(huì)報(bào)錯(cuò),可能在mac上用法不一致。
# 在第3行上方增加一行
sed "3i insert oneline above 3rd line" text.txt
# 在第3行下方增加一行
sed "3a aabbccddeeff" text.txt
# 在第3行創(chuàng)建一行記錄,原記錄被替換
sed "3c abcdefg" text.txt
修改
上述所有的操作輸出均沒有改變文件自身的內(nèi)容。想要使得操作改變文件自身的內(nèi)容,需要指定選項(xiàng)-i。指定-i的操作需要格外小心。
例如,在文件中第一行插入一行記錄:
sed -i "1i 11111111111111111" text.txt
sed的刪除動(dòng)作為d(delete),例如刪除文件中的第一行:
sed -i 1d text.txt
當(dāng)然,我們也有辦法做安全的刪除操作,即將-i換成-i.bak 可以在真實(shí)改動(dòng)文件內(nèi)容前,備份文件。但是這個(gè)操作一般不適合應(yīng)用在大文件上,因?yàn)閭浞莺苈?/p>
sed -i.bak 1d text.txt
替換
sed可以對(duì)文件內(nèi)容進(jìn)行替換(substitute),格式為使用任意三個(gè)相同的符號(hào),如三個(gè)斜線s/xx/yy/g、三個(gè)#號(hào)s#xx#yy#g、三個(gè)@符號(hào)s@xx@yy@g等,效果是將xx替換為yy。
這里的符號(hào)選擇是任意的,可以是三個(gè)1,三個(gè)2都行。常用的是上述三種,因?yàn)楹臀募?nèi)容重合度最小,具體使用哪種,需要根據(jù)文件內(nèi)容選擇。如果文件內(nèi)容本身包含了/,則不方便使用三個(gè)斜線來操作。
# 將青替換為蜀
sed 's/青/蜀/g' text.txt
# 將第3行的青替換為蜀
sed '3s/青/蜀/g' text.txt
# 把所有數(shù)字替換為x
sed -r 's/[0-9]/x/g' text.txt
g是全局(gloabal)替換的意思,如果不要g,則只會(huì)替換匹配到的第一項(xiàng):
# 把每一行的第一個(gè)數(shù)字替換為x
sed 's/[0-9]/x/' test.txt
方向引用
反向引用就是利用正則的組匹配來以組為單位進(jìn)行替換。
sed -r 's/([a-z_.]+)/<\1>/g' test.txt
awk
取行
awk可以通過NR(Number of Record) 指定行號(hào),輸出特定的行:
awk NR==3 test.txt
也可以按行號(hào)范圍輸出:
# 輸出第3行到第6行
awk "NR==3, NR==6" test.txt
或者
awk NR==3,NR==6 test.txt
# 也可以通過比較指定輸出范圍
# 輸出3到4行
awk "NR>=3 && NR<5" test.txt
第二個(gè)NR如果是個(gè)無(wú)效的行號(hào)值,則默認(rèn)取出指定起始行之后所有的行記錄:
# 輸出第3行之后的所有行
awk "NR>=3, NR<xx" test.txt
取行操作依然支持正則匹配:
# 輸出包含青的行
awk '/青/' test.txt
# 輸出以號(hào)結(jié)尾的行
awk '/號(hào)$/' test.txt
# 輸出包含domain到包含addr的行
awk '/domain/,/addr/' test.txt
取列
awk可以使用{print $列號(hào)} 取出列值:
# 例如取出第2列的值
awk '{print $2}' test.txt
# 取出第2列及最后一列NF(Number of Fields)的值
awk '{print $2,$NF}' test.txt
# 使用column -t 對(duì)齊輸出
awk '{print $2,$NF}' test.txt | column -t
awk取列時(shí),默認(rèn)是空格為分隔符,可以通過-F指定分隔符,例如,第7-8行:
awk "NR==7,NR==8" test.txt
取出第7、8行后,按/進(jìn)行劃分,取出劃分后的第二列:
awk 'NR>=7 && NR<9' test.txt |awk -F/ '{print $2}'
-F 可以通過[]正則指定多個(gè)分隔符:
# 按空格和/ 進(jìn)行分隔, 取出1到4列
awk 'NR>=7 && NR<9' test.txt | awk -F'[ /]+' '{print $1,$2,$3,$4}'
精確取行列
awk可以精確取出某一行某一列的值。一些用例如:
# ~ 表示包含, !~ 表示不包含
# 取出第四列包含"青"的行
awk '$4 ~ /青/' test.txt
# 取出第四列以"號(hào)"結(jié)尾的行,并輸出最后一列
awk '$4 ~ /號(hào)$/{print $NF}' test.txt
# 取出第2列以d開始,到第四列以號(hào)結(jié)尾的行記錄
awk '$2 ~ /^d/, $4 ~ /號(hào)$/' test.txt
BEGIN
awk可以使用BEGIN在操作文件內(nèi)容前執(zhí)行一些命令:
# 列如輸出表頭
awk 'BEGIN{print "序號(hào)", "名稱", "含義", "示例"} {print $1,$2,$3,$4}' test.txt |column -t
END文章來源:http://www.zghlxwxcb.cn/news/detail-452227.html
awk可以使用END在操作文件內(nèi)容后執(zhí)行一些命令:文章來源地址http://www.zghlxwxcb.cn/news/detail-452227.html
# 通常用于做統(tǒng)計(jì), 例如對(duì)第一列求和
awk '{sum+=$1}END{print sum}' test.txt
使用小結(jié)
- gep、sed、awk都可以過濾行記錄,但過濾行記錄時(shí)優(yōu)先選擇grep,其過濾行的效率最高
- sed主要用于對(duì)文件內(nèi)容做出各種修改(如增加、替換等)
- awk主要用于對(duì)文件內(nèi)容取行列操作
到了這里,關(guān)于linux命令三劍客grep、sed、awk的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!