簡述
awk、grep、sed是linux操作文本的三大利器,合稱文本三劍客,三者的功能都是處理文本,但側重點各不相同,其中屬awk功能最強大,但也最復雜。grep更適合單純的查找或匹配文本,sed更適合編輯匹配到的文本,awk更適合格式化文本,對文本進行較復雜格式處理。
grep
grep (Global Regular Expression Print)用於搜索/過濾特定字符,可以使用正則表達式通過返回一個狀態值來說明,如果模板搜索成功,返回0,不成功,返回1,文件不存在,返回2;可以利用返回值進行自動化的文本處理工作。
egrep = grep -E:擴展的正則表達式 (除了< , > , \b 使用其他正則都可以去掉\)
#輸出file中含有hello字符串的行的數量
grep -c "hello" file
#輸出file中含有hello的數量
grep -o "hello" file | wc -l
#遞歸查找指定文件或目錄中含有hello的行,並輸出;
grep -r "hello" /etc
#查找含有hello或者world的行;
grep -e "hello" -e "world" file
#搜索src目錄中.c和.cpp文件中含有main的行;
grep -r "main" ./src --include *.{c,cpp}
#搜索src目錄中含有main的行,但不搜索abc文件;
grep -r "main" ./src --exclude "abc"
#搜索src目錄中含有main的行,但不搜索.git文件夾;
grep -r "main" ./src --exclude-dir ".git"
#刪除含有hello字符串的文件
grep -r "hello" ./src -lZ | xargs -0 rm -f
#將file中含有root的行取出
grep root file
or
cat file | grep root
#將沒有root的行取出
grep -v root /home/file
#將沒有出現root和nologin的行取出
grep -v root /etc/passwd | grep -v nologin
#在當前目錄查找帶有’hello‘行的文件
grep 'hello' *
#在當前目錄及子目錄下搜索’hello‘行的文件,但不顯示匹配的行,顯示匹配的文件;
grep -i -r 'hello' *
#過濾注釋行和空行
grep -Ev "^$|[#;]" file1
#在文件'file1'里查找"str"
grep str /home/file1
#在'home'目錄和子目錄的文件中查找"str"
grep str -r /home/*
awk
awk是一種編程語言,用於在linux/unix下對文本和數據進行處理。數據可以來自標准輸入(stdin)、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。它在命令行中使用,但更多是作為腳本來使用。awk有很多內建的功能,比如數組、函數等,這是它和C語言的相同之處,靈活性是awk最大的優勢。
取行和列
#獲取文本第1,3列的值,NF表示字段數,在執行過程中對應於當前的字段數,$為行尾定位符
awk '{print $1,$3}' log.txt
#取最后一列
awk ‘{print $NF}'
#取指定行,NR表示從awk開始執行后,按照記錄分隔符讀取的數據次數,默認的記錄分隔符為換行符,因此默認的就是讀取的數據行數
ps -aux|awk 'NR==3'
#輸出匹配的列
docker images|awk '/d2/ {print $3}'
#取m行到n行中的k字段
awk 'NR==m,NR==n {print $k}' filename
# 取n行k列
awk 'NR==m {print $k}' filename
#獲取內存可用量並且判斷是否小於1024
FreeMem=`free -m | grep Mem | awk '{print $4}'[ $FreeMem -lt 1024 ] && echo "Insufficient Memory"
#匹配行首和行尾
awk '/^xxx.*?yyy/'
#統計行數
awk 'BEGIN { i=0 } { i++ } END { print i}' filename
or
awk 'END { print NR }' filename
#print能夠接受參數;
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3 ; }' //該命令輸出如下 v1 v2 v3
#awk 默認的分割符為空格和制表符,使用 -F 參數來指定分隔符
awk -F ':' '{print $1}' /etc/passwd
#計算剩余內存百分比
free -m | awk 'NR==2' | awk '{a=$2; b=$4; print b / a * 100}'
#它會在開始讀取一個文件之前,運行一次 BEGIN關鍵字后面的腳本代碼段,BEGIN后面的腳本代碼段只會執行一次
awk 'BEGIN {print "Start read file"} {print $0}' /etc/passwd
#在 awk 讀取並且處理完文件的所有內容行之后,才會執行 END 后面的腳本代碼段
awk 'END {print "End file"}' /etc/passwd
awk 'BEGIN {print "Start read file"} {print $0} END {print "End file"}' /etc/passwd
sed
sed是一種流編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(patternspace ),接着用sed 命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。然后讀入下行,執行下一個循環。如果沒有使諸如‘D’ 的特殊命令,那會在兩個循環之間清空模式空間,但不會清空保留空間。這樣不斷重復,直到文件末尾。文件內容並沒有改變,除非你使用重定向存儲輸出或-i。
功能:主要用來自動編輯一個或多個文件, 簡化對文件的反復操作
插入和修改
#插入指定行的下一行
sed -i '101 a\ 1111'
#將test替換為mytest,sed 命令一般是寫在單引號內,引號內開頭的 s 表示替換(substitute)
sed 's/test/mytest/' file
#在默認情況下,sed 只會替換每行中匹配到的第一個字符串,如果希望替換每一行中所有匹配到的字符串,需加在命令末尾上選項 g
sed 's/Jack/Mark/g' fin.txt
# 2~3 行中的 hello 替換成 hey
sed '2,3s/hello/hey/g' fin.txt
#在指定某一行的前面或者后面添加一行
sed -i '1i\welcome' fin.txt
#這里的 1 表示第一行, i 表示在這一行前面添加一行,如果要在第一行后面添加一行,則用字母 a :
sed -i '1a\welcome' fin.txt
#字母 a 是 append ,在后面添加一行
#字母 i 是 insert, 在前面添加一行
#在匹配行的前面或者后面添加一行
sed -i '/Pony/a\welcome' fin.txt
#在后面添加一行用字母 a,在前面添加一行用字母 i
sed -i '/Pony/i\welcome' fin.txt
#找出包含字符 Pony 的那些行,將這些行中的 hello 替換成 hey
sed '/Pony/s/hello/hey/g' fin.txt
#在1111之 前 添加AAA,sed -i 's/指定的字符/要插入的字符&/' 文件
sed -i 's/1111/AAA&/' /tmp/input.txt
#在1111之 后 添加BBB,sed -i 's/指定的字符/&要插入的字符/' 文件
sed -i 's/1111/&BBB/' /tmp/input.txt
#刪除 2~3 行,命令中的 d 表示刪除(delete)
sed '2,3d' fin.txt
#刪除包含字符串 Pony 的行
sed '/Pony/d' fin.txt
#刪除不包含字符 Pony 的行,這里的感嘆號!表示反選,斜杠表示轉義
sed '/Pony/\!d' fin.txt
#刪除空白行, 這里的 ^ 匹配一行的開頭, $ 匹配一行的結尾,所以 /^$/ 就表示一行的開頭和結尾之間沒有任何內容,也就是空白行;
sed '/^$/d' fin.txt
#注意有時候有些空白行是包含空格的,這種情況就需要寫成:
sed '/^\s*$/d' fin.txt
#其中 \s 表示空格, 星號 * 表示前面的字符重復 0 次或多次,所以這種寫法可以匹配那些包含任意個空格的空白行
#刪除字符“,”
echo "hello,123,word" | sed 's/,//g'