流編輯器:sed
語法:sed [-hnV][-e<script>][-f<script文件>][文本文件]
1、參數:
- -e<script>或--expression=<script> 以選項中指定的script來處理輸入的文本文件。
- -f<script文件>或--file=<script文件> 以選項中指定的script文件來處理輸入的文本文件。
- -h或--help 顯示幫助。
- -n或--quiet或--silent 僅顯示script處理后的結果。
- -V或--version 顯示版本信息。
- -i 直接編輯原文件,在原文件中操作
例子:
sed -i 's/原字符串/新字符串/' file #原文件中僅替換每行首次匹配到的原字符串,若一行有多個該字符串,只有第一個被替換(1行只替換1次)
sed -i 's/原字符串/新字符串/g' file #在原文件中替換,后綴 g 意味着會替換每一處匹配,而不是每一行中第一次匹配
sed 's/原字符串/新字符串/g' file #不加 -i 參數,將替換后的文本都打印出來,但原文件不變
sed 's/原字符串/新字符串/g' file > newfile #同上,替換后的文本打印到新文件中
sed -i '/^$/d' file #在原文件中移除空白行,^$表示空白行,d表示將匹配的樣式移除,注意:由空格組成的行不能算空白行
sed -i 's/max_execution_time = 30/max_execution_time = 300/g' /etc/php/php.ini #修改php配置文件的配置
文本混亂與恢復正常(替換空格,換行符,制表符等)
cat test.js | sed 's/;/;\n/g; s/{/{\n\n/g; s/}/\n\n}/g' # s/;/;\n/g將;替換為\n; s/{/{\n\n/g將{替換為{\n\n s/}/\n\n/g將}替換為\n\n}
cat test.js | sed 's/;/;\n/g' |sed 's/{/{\n\n/g' | sed 's/}/\n\n}/g' #同上
sed 's/ [^.]*mobbile phones[^.]*\.//g' test.txt #移除文件test.txt中包含單詞“mobile phones”的句子
- a :新增, a 的后面可以接字串,而這些字串會在新的一行出現(目前的下一行)~
- c :替換, c 的后面可以接字串,這些字串可以取代 n1,n2 之間的行!
- d :刪除,因為是刪除啊,所以 d 后面通常不接任何東西;
- i :插入, i 的后面可以接字串,而這些字串會在新的一行出現(目前的上一行);
- p :打印,亦即將某個選擇的數據印出。通常 p 會與參數 sed -n 一起運行~
- s :替換(匹配局部替換),可以直接進行取代的工作哩!通常這個 s 的動作可以搭配正規表示法!例如 1,20s/old/new/g 就是啦!
新增 a
sed -i '2a testContent' test.txt #在第 2 行后面新增一行內容
sed -i '1,3a testContent' test.txt #在原文的第 1~3 行后面各新增一行內容
sed -i '$a This is a test' test.txt #在文件末尾加一行 This is a test,$表示最后一行
sed -e '4 a newline' test.txt #在4行之后新增一行
sed -e '4 a newline\nnewline2' test.txt #在4行之后新增兩行,\n 表示換行,增加3行同理,加上\n接上內容
替換 c
sed -i '2c testContent' test.txt #將第 2 行內容整行替換
sed -i '1,3c testContent' test.txt #將第 1~3 行內容替換成一行指定內容
刪除 d
sed -i '2d' test.txt #刪除第 2 行
sed -i '1,3d' test.txt #刪除第1~3行
sed -i 's/^ *//' test.txt #刪除行首空格
sed -i 's/^[[:space:]]*//' test.txt #去掉test.txt中每行行首的制表符和空格
sed -i 's/^[0-9]* *//' test.txt #去掉test.txt每行行首的數字
插入 i
sed '2i testContent' test.txt #在第 2 行前面插入一行內容
sed '1,3i testContent' test.txt #在原文的第 1~3 行前面各插入一行內容
打印 p
sed '2p' test.txt #重復打印第 2 行
sed '1,3p' test.txt #重復打印第1~3行
sed -n '2p' test.txt #只打印第 2 行
sed -n '1,3p' test.txt #只打印第 1~3 行
sed -n '/user/p' test.txt #打印匹配到user的行,類似grep
sed -n '/user/!p' test.txt #!!!反選,打印沒有匹配到user的行
sed -n 's/old/new/gp' test #只打印匹配替換的行
sed -n '1~2p' test.txt #打印奇數行
sed -n '2~2p' test.txt #打印偶數行
sed -n 'p;n' test.txt #打印奇數行
sed -n 'n;p' test.txt #打印偶數行
替換 s
sed -i 's/old/new/' test.txt #匹配每一行的第一個old替換為new
sed 's/[ ][ ]*/ /g' test.txt #替換兩個或多個空格為一個空格
sed 's/[ ][ ]*/:/g' test.txt # 替換兩個或多個空格為分隔符:
sed 's/[[:space:]][[:space:]]*/ /g' test.txt #如果空格與tab共存時替換成空格
sed 's/[[:space:]][[:space:]]*/:/g' test.txt #如果空格與tab共存時替換成分隔符:
sed -i 's/old/new/gi' test.txt #匹配所有old替換為new,g 代表一行多個,i 代表匹配忽略大小寫
sed -i '3,9s/old/new/gi' test.txt #匹配第 3~9 行所有old替換為new
數據流工具:awk
語法
awk [選項參數] 'script' var=value file(s) 或 awk [選項參數] -f scriptfile var=value file(s)
選項參數:
- -F fs or --field-separator fs
指定輸入文件折分隔符,fs是一個字符串或者是一個正則表達式,如-F:。 - -v var=value or --asign var=value
賦值一個用戶定義變量。 - -f scripfile or --file scriptfile
從腳本文件中讀取awk命令。 - -mf nnn and -mr nnn
對nnn值設置內在限制,-mf選項限制分配給nnn的最大塊數目;-mr選項限制記錄的最大數目。這兩個功能是Bell實驗室版awk的擴展功能,在標准awk中不適用。 - -W compact or --compat, -W traditional or --traditional
在兼容模式下運行awk。所以gawk的行為和標准的awk完全一樣,所有的awk擴展都被忽略。 - -W copyleft or --copyleft, -W copyright or --copyright
打印簡短的版權信息。 - -W help or --help, -W usage or --usage
打印全部awk選項和每個選項的簡短說明。 - -W lint or --lint
打印不能向傳統unix平台移植的結構的警告。 - -W lint-old or --lint-old
打印關於不能向傳統unix平台移植的結構的警告。 - -W posix
打開兼容模式。但有以下限制,不識別:/x、函數關鍵字、func、換碼序列以及當fs是一個空格時,將新行作為一個域分隔符;操作符**和**=不能代替^和^=;fflush無效。 - -W re-interval or --re-inerval
允許間隔正則表達式的使用,參考(grep中的Posix字符類),如括號表達式[[:alpha:]]。 - -W source program-text or --source program-text
使用program-text作為源代碼,可與-f命令混用。 - -W version or --version
打印bug報告信息的版本。
工作方式:
awk 'BEGIN{ PRINT "start" } pattern { commands } END{print "END" } file
首先執行BEGIN語句塊,然后從文件或stdin中讀取一行,然后執行pattern{ commands }。直到文件全部讀取完畢。讀到輸入流末尾時,執行END{ commands } 語句塊。三個語句塊都是可選的。如果沒有提供pattern語句塊則默認打印每一個讀取到行。
awk的特殊變量:
NR:表示記錄數量,在執行過程中對應於當前行號。
NF:表示字段數量,在執行過程中相對於當前行的字段數。
$NF:表示當前行的最后一個字段。$(NF-1)表示當前行的倒數第二個字段。依次類推
$0:這個變量包含執行過程中當前行的文本內容。
$1:這個變量包含第一個字段的文本內容。
$2:這個變量包含第二個字段的文本內容。依次類推。
awk 'BEGIN { i=0 } { i++ } END{ print i }' filename #逐行讀取文件並打印行數
echo -e "line1\nline2" | awk 'BEGIN{ print "Start" } { print } END { print "END" } '
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"-"var2"-"var3;}'
echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7" | awk '{ print "Line no:"NR",No of fields:"NF, "$0="$0,"$1="$1,"$2="$2,"$3="$3 }'
awk '{ print $3,$2 }' file #打印文件中每一行的第2和第3個字段。
awk 'END{ print NR }' file #統計文件中的行數,只加END語句塊表示文件執行到最后一行時再輸出行號
awk 'NR < 5' file #打印文件中行號小於5的行
awk 'NR==2,NR==5' file #打印文件中行號在2到5之間的行
awk '/linux/' file #打印文件中包含樣式linux的行(樣式可以使用正則表達式)
awk '1/linux/' file #打印文件中不包含包含樣式linux的行
awk -F: '{ print $NF }' /etc/passwd #讀取並打印/etc/passwd文件的內容,設置定界符為":",默認的定界符為空格
var1='test'; var2='text' #(1)外部變量
echo | awk '{ print v1,v2 } v1=$var1 v2=var2 #(2)打印多個從標准輸入傳給awk的外部變量
awk '{ print v1,v2 }' v1=$var1 v2=var2 filename #(3)輸入來自文件
cat test.txt | getline output #將cat的輸出讀入變量output中。
awk 'BEGIN { FS=":" } { print $NF }' /etc/passwd #BEGIN語句塊中則使用FS="delimiter"設置輸出字段的定界符
awk '{arr[$1]+=1 }END{for(i in arr){print arr[i]"\t"i}}' FILE_NAME | sort -rn #統計每個單詞的出現頻率並排序
seq 5 | awk 'BEGIN{ sum=0;print "Summation:" } { print $1"+"; sum+=$1 } END{ print "=="; print sum }' #將每一行第一個字段的值按照給定形式進行累加
echo | awk '{ "grep root /etc/passwd" | getline cmdout; print cmdout }' #通過getline將外部shell命令的輸出讀入變量cmdout。變量cmdout包括命令grep root /etc/passwdde 的輸出,然后打印包含root的行。
awk中使用循環與awk的內建函數
for(i=0;i<10;i++){ print $i; } 或者 for( i in array ) { print array[i]; }
length(string):返回字符串的長度
index(string ,search_string):返回search_string在字符串中出現的位置。
split(string, array, delimiter):用界定符生成一個字符串列表,並將該列表存入數組
substr(string, start-position, end-position):在字符串中用字符起止偏移量生成子串,並返回該子串。
sub(regex, replacement_str, string):將正則表達式匹配到的第一處內容替換成replacement_str。
gsub(regex, replacement_str, string):將正則表達式匹配到的所有內容替換成replacement_str。
match(regex ,string):檢查正則表達式是不能夠匹配字符串,若能,返回非0值;否則,返回0.
cat access.log | awk '{ if($9=200) print $7;}' #分析nginx訪問日志,awk不加 -f 參數表示使用空格(默認的分詞字符)拆分該行,$9表示第9個字段(也就是HTTP CODE),$7表示第7個字段,表示用戶訪問的文件
awk '{print $1}' access.log |sort|uniq -c|sort -nr|head -10 #分析access.log獲得訪問前10位的ip地址
awk -F '[,:]' '{if($6==140) print $0;}' test.log #對test.log中每行用“,”和“:”分割,並打印出分割后第6個字段等於140的行
cat *_login.log | awk -F[,:] '{if($24<1541260800) print $24;}' | wc -l #統計所有login日志中時間戳(拆分后第24個字段)小於1541260800的行數
awk -F: '{print $15}' test.log | awk -F, '{print $1}' | awk '{for(i=0;i<NF;i++) sum+=$i;}END{print sum}' #對test.log的json行先用“:”分割再用“,”分割,再對某個字段累加
awk -F, '{print $14}' test.log | awk -F: '{print $2}' | awk '{for(i=0;i<NF;i++) sum+=$i;}END{print sum}' #對test.log的json行先用“,”分割再用“:”分割再對某個字段累加
awk -F '[,:]' '{print $28}' test.log | awk '{for(i=0;i<NF;i++) sum+=$i;}END{print sum}' #對test.log的json行分別用“,”和“:”分割后再對某個字段累加
awk -F[:,] '{print $28;}' pay.log | awk -F\" '{print $2;}' | awk '{for(i=0;i<NF;i++) sum+=$i;}END{print sum}' #作用同上,在拆分后字段還包含雙引號的情況下,再次拆分,獲取數字再累加
---------------------------------------------------------------------------------------------------------------------------------------
文件:test.log 內如如下:
{"sid":1,"cid":1,"channel":140,"zid":0,"uid":"140524293334","role_id":"100252","goods_id":7,"cny":110000,"eventtime":1540244075}
{"sid":1,"cid":1,"channel":140,"zid":0,"uid":"140524293334","role_id":"100252","goods_id":7,"cny":120000,"eventtime":1540244075}
命令:
awk -F ':' '{print $9}' test.log | awk -F ',' '{print $1}' #先使用 “:”為分隔符分割test.log每一行,然后獲取第9個字段,再用“,”為分隔符分割字符串,再取第一個字段。
結果:
110000
120000
若是要統計該字段的累加數:
awk -F ':' '{print $9}' test.log | awk -F ',' '{print $1}' | awk '{for(i=1;i<=NF;i++) sum+=$i;} END{print sum}'
結果:
230000
----------------------------------------------------------------------------------------------------------------------------------------
替換工具:tr
語法
tr [-cdst][--help][--version][第一字符集][第二字符集] tr [OPTION]…SET1[SET2]
參數:
- -c, --complement:反選設定字符。也就是符合 SET1 的部份不做處理,不符合的剩余部份才進行轉換
- -d, --delete:刪除指令字符
- -s, --squeeze-repeats:縮減連續重復的字符成指定的單個字符
- -t, --truncate-set1:削減 SET1 指定范圍,使之與 SET2 設定長度相等
- --help:顯示程序用法信息
- --version:顯示程序本身的版本信息
例子:
echo 12345 | tr '0-9' '9876543210' #加密
echo 87654 | tr '9876543210' '0-9' #解密
echo "Hello 123 world 456" | tr -d '0-9' #使用-d將stdin中的數字刪除並打印出來
cat test.txt | tr -d '0-9' #同上
echo "hello 1 char 2 next 3 " | tr -d -c '0-9 \n' #參數-c是使用補集。刪除stdin中的所有數字和換行符之外的字符(這些字符是'0-9 \n'這個集合的補集)
echo "this is a test !" | tr -s ' ' #參數-s壓縮多個空格為單個
------------------------------------------------
tr可以像使用集合一樣使用各種不同的字符類:
alnum:字母和數字
alpha:字母
cntrl:控制(非打印)字符
digit:數字
graph:圖形字符
lower:小寫字母
print:可打印字符
punct:標點符號
space;空白字符
upper:大寫字母
xdigit:十六進制字符
使用方式:
tr [:class:] [:class:]
例如:
tr '[:lower:]' '[:upper:]' #將所有小寫字母換成大寫字母
----------------------------------------------------