天天看點

Linux基礎篇之文本、資料流處理指令(sed uniq grep awk wc)

1 awk:文本和資料處理工具

awk擅長于對資料進行分析并生成報告,簡單來說awk就是把檔案逐行的讀入,以空格為預設分隔符将每行切片,切開的部分再進行各種分析處理。

使用方法:awk '{pattern + action}' {filenames}  

其中pattern 表示awk 在資料中查找的内容,而action是在找到比對内容時所執行的一系列指令。花括号({})不需要在程式中始終出現,但它們用于根據特定的模式對一系列指令進行分組。pattern就是要表示的正規表達式,用斜杠括起來。準備執行個體操作檔案:netstat  -t >> netstat.txt

1.1 列印輸出:print,格式化列印輸出:printf

awk '{print$1, $4}' netstat.txt

awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}' netstat.txt

1.2 過濾記錄:awk '$3==0 && $6=="LISTEN"' netstat.txt

其中的“==”為比較運算符。其他比較運算符:!=,>, <, >=, <=

awk '$3>0 {print $0}' netstat.txt

加入表頭:内建變量NR

awk '$3==0 && $6=="LISTEN" || NR==1 ' netstat.txt

再加上格式化輸出                     

awk '$3 ==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt

ps:awk的内建變量

$0 目前記錄(這個變量中存放着整個行的内容)
$1~$n 目前記錄的第n個字段,字段間由FS分隔
FS 輸入字段分隔符預設是空格或Tab
NF 目前記錄中的字段個數,就是有多少列
NR 已經讀出的記錄數,就是行号,從1開始,如果有多個檔案話,這個值也是不斷累加中。
FNR 目前記錄數,與NR不同的是,這個值會是各個檔案自己的行号
RS 輸入的記錄分隔符,預設為換行符
OFS 輸出字段分隔符,預設也是空格
ORS 輸出的記錄分隔符,預設為換行符
FILENAME 目前輸入檔案的名字

輸出行号:awk '$3 ==0 && $6=="ESTABLISHED"|| NR==1 {printf "%02s %s %-20s %-20s %s\n",NR, FNR,$4,$5,$6}' netstat.txt

指定分隔符:awk 'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd

或者awk -F: '{print $1,$3,$6}' /etc/passwd

以\t作為分隔符輸出:awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd

1.3 字元串比對:~表示比對模式開始,正規表達式比對。

awk '$6 ~ /TIME/ || NR ==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

awk '$6 ~ /ESTABLISHED/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

awk '/LISTEN/' netstat.txt

使用“/TIME|ESTABLISHED/” 來比對TIME 或者ESTABLISHED :

awk '$6 ~ /FIN|TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

模式取反:!~

awk '$6 !~ /TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

或者awk '!/WAIT/' netstat.txt

1.4 拆分檔案:使用資料流重定向”>”

awk 'NR!=1 {print > $6}' netstat.txt      NR!=1表示不處理表頭

把指定的列輸出到檔案:  awk 'NR!=1{print $4,$5 > $6}' netstat.txt

使用程式流進行條件拆分:if else

awk 'NR!=1{if($6 ~ /TIME|ESTABLISHED/) print > "1.txt";

else if($6 ~ /LISTEN/) print > "2.txt";

else print > "3.txt"}' netstat.txt

1.5 統計

計算所有的C檔案,CPP檔案和H檔案的檔案大小總和:

ls -l *.cpp *.c*.h | awk '{sum+=$5} END {print sum}'

統計各個connection狀态的用法:使用數組

awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}' netstat.txt

統計每個使用者的程序的占了多少記憶體:

ps aux| awk 'NR!=1{a[$1]+=$6;} END { for(i ina) print i ", " a[i]"KB";}'

數組:因為awk中數組的下标可以是數字和字母,數組的下标通常被稱為關鍵字(key)。值和關鍵字都存儲在内部的一張針對key/value應用hash的表格裡。由于hash不是順序存儲,是以在顯示數組内容時會發現,它們并不是按照你預料的順序顯示出來的。數組和變量一樣,都是在使用時自動建立的,awk也同樣會自動判斷其存儲的是數字還是字元串。一般而言,awk中的數組用來從記錄中收集資訊,可以用于計算總和、統計單詞以及跟蹤模闆被比對的次數等等。

1.6 使用腳本進行文本、資料處理

BEGIN、END關鍵字:BEGIN表示處理所有行之前的辨別,END表示處理完所有行後的辨別,具體文法:

BEGIN{ 這裡面放的是執行前的語句}

END {這裡面放的是處理完所有的行後要執行的語句}

{這裡面放的是處理每一行時要執行的語句}

執行個體操作檔案:cat cal.awk

#!/bin/awk -f

#運作前

BEGIN {

   math= 0

   english= 0

   computer= 0

   printf"NAME    NO.     MATH  ENGLISH  COMPUTER   TOTAL\n"

   printf"---------------------------------------------\n"

}

#運作中

{

   math+=$3

   english+=$4

   computer+=$5

   printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5

}

#運作後

END{

   printf"---------------------------------------------\n"

   printf "TOTAL:%10d %8d %8d \n", math, english, computer

   printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR,computer/NR

}

執行:awk -f cal.awk score.txt

1.7 變量聲明和環境變量:使用-v參數進行變量聲明,ENVIRON關鍵字表示環境變量

$ x=5

$ y=10

$ export y                          #y被export為環境變量

$ echo $x $y

5    10

$awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt

2 sed:流編輯器

stream editor,流編輯器,用程式的方式來編輯文本,正規表達式進行模式比對。sed本身是一個管道指令,可以分析standard input,也可以将資料進行替換、删除、新增、颉取特定行等功能。

示範文本:catpets.txt

This is my cat

my cat's name is betty

This is my dog

my dog's name is frank

This is my fish

my fish's name is george

This is my goat

my goat's name is adam

使用:sed [-nefr] action

action:-i直接修改讀取的檔案内容,而不是由螢幕輸出,-r表示支援延伸型正規表達式的文法。

動作說明:[n1[,n2]] function n1,n2表示要選擇的行數,function包括:

a-新增,c-取代,d-删除,i-插入,p-列印,s-取代(可以直接進行取代的工作,例如 1,20s/old/new/g)

2.1 用s指令進行替換

my字元串替換成Rango Chen’s

sed “s/my/Rango Chen's/g” pets.txt

ps:如果使用單引号,則無法通過\'來轉義。該指令并沒有對檔案内容進行更改,隻是把處理過後的内容輸出,如果你要寫回檔案,你可以使用重定向:sed "s/my/Rango Chen's/g" pets.txt >Chen_pets.txt,或者使用-i選項:sed -i “s/my/Rango Chen's/g” pets.txt

s表示替換動作,/g表示一行上的替換所有的比對。

在每一行最前面加上#:sed 's/^/#/g' pets.txt        

在每一行的末尾加上---:sed 's/$/ --- /g' pets.txt    

基礎的正則表示法特殊字元:

^ 表示一行的開頭。如:/^#/ 以#開頭的比對。

$ 表示一行的結尾。如:/}$/ 以}結尾的比對。

\< 表示詞首。如\<abc 表示以abc 為首的詞。

\> 表示詞尾。如 abc\> 表示以abc 結尾的詞。

\  将特殊字元進行轉義,還原其本身意義:grep -n  \' pets.txt 搜尋含有單引号'的那一行。

. 表示任何單個字元。

* 表示某個字元出現了0次或多次。

[ ] 字元集合。如:[abc]表示比對a或b或c,還有[a-zA-Z]表示比對所有的26個字元。如果其中有^表示取反,如[^a]表示非a的字元

\{n,m\} 連續n到m個的“前一個RE字元” grep -n 'go\{2,3\}g' 1.txt   在g與g之間有2到3個o存在的字元串,亦即(goog)(gooog)

去掉某html中的tags:html.txt:

   <b>This</b>is what <span style="text-decoration:underline;">I</span> meant.  Understand?

sed 's/<[^>]*>//g' html.txt

隻替換第3到第6行的文本:sed "3,6s/my/your/g" pets.txt

隻替換第3行的文本:sed "3s/my/your/g" pets.txt

隻替換每一行的第一個s:sed 's/s/S/1' my.txt   1表示第一個

隻替換每一行的第二個s:sed 's/s/S/2' my.txt    2表示第二個

隻替換第一行的第3個以後的s:sed 's/s/S/3g' my.txt

2.2 多個比對

一次替換多個模式,每個模式之間用;進行間隔:sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt

上面的指令等價于:sed -e'1,3s/my/your/g' -e '3,$s/This/That/g' my.txt

使用&來當做被比對的變量,加入一些字元:sed 's/my/[&]/g' my.txt

此指令相當于在my兩邊加上[]

2.3 圓括号比對

圓括号括起來的正規表達式所比對的字元串會可以當成變量來使用,sed中使用的是\1,\2…

[,]∗,.*is .∗/\1:\2/g' my.txt

cat:betty

dog:frank

fish:george

goat:adam

2.4 基本知識點

1)Pattern Space:關于參數-n,表示取消預設輸出,相當于--quiet,--silent。在sed處理檔案的時候,每一行都被儲存在一個叫模式空間的臨時緩沖區中,除非行被删除或者輸出被取消,否則所有被處理的行都将列印在螢幕上。接着模式空間被清空,并存入新的一行等待處理。

2)Address:[address[,address]][!]{cmd},其中的!表示比對成功後是否執行指令,address可以是一個數字,也可以是一個模式,可以通過逗号分隔兩個address表示兩個address的區間。

3)指令打包:cmd可以是多個,它們可以用分号分開,可以用大括号括起來作為嵌套指令

對3行到第6行,比對/This/成功後,再比對/fish/,成功後執行d指令:

sed '3,6 {/This/{/fish/d}}' pets.txt

從第一行到最後一行,如果比對到This,則删除之;如果前面有空格,則去除空格:

sed '1,${/This/d ; s/^ *//g}' pets.txt

4)HoldSpace:保持空間

g:将hold space中的内容拷貝到pattern space中,原來pattern space裡的内容清除

G:将hold space中的内容append到pattern space\n後

h:将pattern space中的内容拷貝到hold space中,原來的hold space裡的内容被清除

H:将pattern space中的内容append到hold space\n後

x:交換pattern space和hold space的内容

sed -e '/test/h' -e '$G‘  example:在這個例子裡,比對test的行被找到後,将存入模式空間,h指令将其複制并存入一個稱為保持緩存區的特殊緩沖區内。第二條語句的意思是,當到達最後一行後,G指令取出保持緩沖區的行,然後把它放回模式空間中,且追加到現在已經存在于模式空間中的行的末尾。在這個例子中就是追加到最後一行。簡單來說,任何包含test的行都被複制并追加到該檔案的末尾。

sed -e '/test/h' -e '/check/x' example:互換模式空間和保持緩沖區的内容。也就是把包含test與check的行互換。

5)執行sed腳本:sed -f test.sed

末尾不能有任何空白或文本,如果在一行中有多個指令,要用分号分隔。以#開頭的行為注釋行,且不能跨行。

ps: 去除空白行:sed '/^ *$/d' file

3 sort:文本内容排序

語  法:sort [-bcdfimMnr] [-o<輸出檔案>] [-t<分隔字元>] [+<起始欄位>-<結束欄位>] [--help] [--verison] [檔案]

參  數:

-b    忽略每行前面開始出的空格字元。

-c    檢查檔案是否已經按照順序排序。

-d    排序時,處理英文字母、數字及空格字元外,忽略其他的字元。

-f    排序時,将小寫字母視為大寫字母。

-i    排序時,除了040至176之間的ASCII字元外,忽略其他的字元。

-m    将幾個排序好的檔案進行合并。

-M    将前面3個字母依照月份的縮寫進行排序。

-n    依照數值的大小排序。

-o<輸出檔案>    将排序後的結果存入指定的檔案。

-r    以相反的順序來排序。

-t<分隔字元>    指定排序時所用的欄位分隔字元。

+<起始欄位>-<結束欄位>    以指定的欄位來排序,範圍由起始欄位到結束欄位的前一欄位。

--help    顯示幫助。

--version    顯示版本資訊

4 uniq:Filter adjacent matching lines from INPUT (or standard input), writingto OUTPUT (or standard output)

顯示唯一的行,對于那些連續重複的行隻顯示一次,以及計數重複的行

uniq:不加任何參數表示比對第一次出現的那行

uniq -c:顯示重複的行的行數

uniq -u:僅顯示檔案中沒有連續出現的行,唯一行

uniq -d:僅顯示檔案中連續重複出現的行。

5 cut:片段颉取工具,可以從一個文本檔案或者文本流中提取文本列

5.1 指令用法

cut -b list [-n] [file ...]        

cut -c list [file ...]

cut -f list [-d delim][-s][file ...]

-b、-c、-f分别表示位元組、字元、字段(即byte、character、field);list表示-b,-c,-f操作範圍,-n表示具體數字,with -b: don’t split multibyte characters;file表示的自然是要操作的文本檔案的名稱;delim(英文全寫:delimiter)表示分隔符,預設情況下為TAB;-s表示不包括那些不含分隔符的行(這樣有利于去掉注釋和标題)。--output-delimiter=字元串,使用指定的字元串作為輸出分界符,預設采用輸入的分界符。上面三種方式中,表示從指定的範圍中提取位元組(-b)、或字元(-c)、或字段(-f)。

LIST的範圍:

N 隻有第N項
N- 從第N項一直到行尾
N-M 從第N項到第M項(包括M)
-M 從一行的開始到第M項(包括M)
- 從一行的開始到結束的所有項

5.2 用法執行個體

颉取/etc/passwd檔案中的前十五個使用者名:

cut -f1 -d: /etc/passwd | head -15

颉取/etc/passwd檔案每一行前十個位元組的内容:

cut -b 1-10 /etc/passwd

颉取該檔案每一行第1,4,7個位元組的内容:

cut -b 1,4,7 /etc/passwd

将/etc/passwd的分隔符換成“|”輸出:

cut -d: -f 1- -s --output-delimiter=”|” /etc/passwd

6 grep:颉取具有特定資訊的行,逐行操作

用法:grep [-acinv] [--color=auto] '搜尋字元串' filename

-a :    将binary檔案以text 檔案的方式搜尋資料

-c:    計算找到'搜尋字元串'的次數

-i:    忽略大小寫的不同,是以大小寫視為相同

-n :    順便輸出行号

-v :    反向選擇,亦即顯示出沒有'搜尋字元串'内容的那一行!

--color=auto:    可以将找到的關鍵詞部分加上顔色的顯示!

7 wc:wordcount,printnewline, word, and byte counts for each file

用法:wc [-lwmc]

-l :    僅列出行;    

-w :    僅列出多少字(英文單字); 

-m :    多少字元;

-c:    多少位元組

不加任何參數表示全部列出。

執行個體:/etc/man.config 裡面有多少相關字、行、字元數:

cat /etc/man.config | wc 

轉自:​​http://rangochen.blog.51cto.com/2445286/1373476​​

1 awk:文本和資料處理工具

awk擅長于對資料進行分析并生成報告,簡單來說awk就是把檔案逐行的讀入,以空格為預設分隔符将每行切片,切開的部分再進行各種分析處理。

使用方法:awk '{pattern + action}' {filenames}  

其中pattern 表示awk 在資料中查找的内容,而action是在找到比對内容時所執行的一系列指令。花括号({})不需要在程式中始終出現,但它們用于根據特定的模式對一系列指令進行分組。pattern就是要表示的正規表達式,用斜杠括起來。準備執行個體操作檔案:netstat  -t >> netstat.txt

1.1 列印輸出:print,格式化列印輸出:printf

awk '{print$1, $4}' netstat.txt

awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}' netstat.txt

1.2 過濾記錄:awk '$3==0 && $6=="LISTEN"' netstat.txt

其中的“==”為比較運算符。其他比較運算符:!=,>, <, >=, <=

awk '$3>0 {print $0}' netstat.txt

加入表頭:内建變量NR

awk '$3==0 && $6=="LISTEN" || NR==1 ' netstat.txt

再加上格式化輸出                     

awk '$3 ==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt

ps:awk的内建變量

$0 目前記錄(這個變量中存放着整個行的内容)
$1~$n 目前記錄的第n個字段,字段間由FS分隔
FS 輸入字段分隔符預設是空格或Tab
NF 目前記錄中的字段個數,就是有多少列
NR 已經讀出的記錄數,就是行号,從1開始,如果有多個檔案話,這個值也是不斷累加中。
FNR 目前記錄數,與NR不同的是,這個值會是各個檔案自己的行号
RS 輸入的記錄分隔符,預設為換行符
OFS 輸出字段分隔符,預設也是空格
ORS 輸出的記錄分隔符,預設為換行符
FILENAME 目前輸入檔案的名字

輸出行号:awk '$3 ==0 && $6=="ESTABLISHED"|| NR==1 {printf "%02s %s %-20s %-20s %s\n",NR, FNR,$4,$5,$6}' netstat.txt

指定分隔符:awk 'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd

或者awk -F: '{print $1,$3,$6}' /etc/passwd

以\t作為分隔符輸出:awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd

1.3 字元串比對:~表示比對模式開始,正規表達式比對。

awk '$6 ~ /TIME/ || NR ==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

awk '$6 ~ /ESTABLISHED/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

awk '/LISTEN/' netstat.txt

使用“/TIME|ESTABLISHED/” 來比對TIME 或者ESTABLISHED :

awk '$6 ~ /FIN|TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

模式取反:!~

awk '$6 !~ /TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

或者awk '!/WAIT/' netstat.txt

1.4 拆分檔案:使用資料流重定向”>”

awk 'NR!=1 {print > $6}' netstat.txt      NR!=1表示不處理表頭

把指定的列輸出到檔案:  awk 'NR!=1{print $4,$5 > $6}' netstat.txt

使用程式流進行條件拆分:if else

awk 'NR!=1{if($6 ~ /TIME|ESTABLISHED/) print > "1.txt";

else if($6 ~ /LISTEN/) print > "2.txt";

else print > "3.txt"}' netstat.txt

1.5 統計

計算所有的C檔案,CPP檔案和H檔案的檔案大小總和:

ls -l *.cpp *.c*.h | awk '{sum+=$5} END {print sum}'

統計各個connection狀态的用法:使用數組

awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}' netstat.txt

統計每個使用者的程序的占了多少記憶體:

ps aux| awk 'NR!=1{a[$1]+=$6;} END { for(i ina) print i ", " a[i]"KB";}'

數組:因為awk中數組的下标可以是數字和字母,數組的下标通常被稱為關鍵字(key)。值和關鍵字都存儲在内部的一張針對key/value應用hash的表格裡。由于hash不是順序存儲,是以在顯示數組内容時會發現,它們并不是按照你預料的順序顯示出來的。數組和變量一樣,都是在使用時自動建立的,awk也同樣會自動判斷其存儲的是數字還是字元串。一般而言,awk中的數組用來從記錄中收集資訊,可以用于計算總和、統計單詞以及跟蹤模闆被比對的次數等等。

1.6 使用腳本進行文本、資料處理

BEGIN、END關鍵字:BEGIN表示處理所有行之前的辨別,END表示處理完所有行後的辨別,具體文法:

BEGIN{ 這裡面放的是執行前的語句}

END {這裡面放的是處理完所有的行後要執行的語句}

{這裡面放的是處理每一行時要執行的語句}

執行個體操作檔案:cat cal.awk

#!/bin/awk -f

#運作前

BEGIN {

   math= 0

   english= 0

   computer= 0

   printf"NAME    NO.     MATH  ENGLISH  COMPUTER   TOTAL\n"

   printf"---------------------------------------------\n"

}

#運作中

{

   math+=$3

   english+=$4

   computer+=$5

   printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5

}

#運作後

END{

   printf"---------------------------------------------\n"

   printf "TOTAL:%10d %8d %8d \n", math, english, computer

   printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR,computer/NR

}

執行:awk -f cal.awk score.txt

1.7 變量聲明和環境變量:使用-v參數進行變量聲明,ENVIRON關鍵字表示環境變量

$ x=5

$ y=10

$ export y                          #y被export為環境變量

$ echo $x $y

5    10

$awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt

2 sed:流編輯器

stream editor,流編輯器,用程式的方式來編輯文本,正規表達式進行模式比對。sed本身是一個管道指令,可以分析standard input,也可以将資料進行替換、删除、新增、颉取特定行等功能。

示範文本:catpets.txt

This is my cat

my cat's name is betty

This is my dog

my dog's name is frank

This is my fish

my fish's name is george

This is my goat

my goat's name is adam

使用:sed [-nefr] action

action:-i直接修改讀取的檔案内容,而不是由螢幕輸出,-r表示支援延伸型正規表達式的文法。

動作說明:[n1[,n2]] function n1,n2表示要選擇的行數,function包括:

a-新增,c-取代,d-删除,i-插入,p-列印,s-取代(可以直接進行取代的工作,例如 1,20s/old/new/g)

2.1 用s指令進行替換

my字元串替換成Rango Chen’s

sed “s/my/Rango Chen's/g” pets.txt

ps:如果使用單引号,則無法通過\'來轉義。該指令并沒有對檔案内容進行更改,隻是把處理過後的内容輸出,如果你要寫回檔案,你可以使用重定向:sed "s/my/Rango Chen's/g" pets.txt >Chen_pets.txt,或者使用-i選項:sed -i “s/my/Rango Chen's/g” pets.txt

s表示替換動作,/g表示一行上的替換所有的比對。

在每一行最前面加上#:sed 's/^/#/g' pets.txt        

在每一行的末尾加上---:sed 's/$/ --- /g' pets.txt    

基礎的正則表示法特殊字元:

^ 表示一行的開頭。如:/^#/ 以#開頭的比對。

$ 表示一行的結尾。如:/}$/ 以}結尾的比對。

\< 表示詞首。如\<abc 表示以abc 為首的詞。

\> 表示詞尾。如 abc\> 表示以abc 結尾的詞。

\  将特殊字元進行轉義,還原其本身意義:grep -n  \' pets.txt 搜尋含有單引号'的那一行。

. 表示任何單個字元。

* 表示某個字元出現了0次或多次。

[ ] 字元集合。如:[abc]表示比對a或b或c,還有[a-zA-Z]表示比對所有的26個字元。如果其中有^表示取反,如[^a]表示非a的字元

\{n,m\} 連續n到m個的“前一個RE字元” grep -n 'go\{2,3\}g' 1.txt   在g與g之間有2到3個o存在的字元串,亦即(goog)(gooog)

去掉某html中的tags:html.txt:

   <b>This</b>is what <span style="text-decoration:underline;">I</span> meant.  Understand?

sed 's/<[^>]*>//g' html.txt

隻替換第3到第6行的文本:sed "3,6s/my/your/g" pets.txt

隻替換第3行的文本:sed "3s/my/your/g" pets.txt

隻替換每一行的第一個s:sed 's/s/S/1' my.txt   1表示第一個

隻替換每一行的第二個s:sed 's/s/S/2' my.txt    2表示第二個

隻替換第一行的第3個以後的s:sed 's/s/S/3g' my.txt

2.2 多個比對

一次替換多個模式,每個模式之間用;進行間隔:sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt

上面的指令等價于:sed -e'1,3s/my/your/g' -e '3,$s/This/That/g' my.txt

使用&來當做被比對的變量,加入一些字元:sed 's/my/[&]/g' my.txt

此指令相當于在my兩邊加上[]

2.3 圓括号比對

圓括号括起來的正規表達式所比對的字元串會可以當成變量來使用,sed中使用的是\1,\2…

[,]∗,.*is .∗/\1:\2/g' my.txt

cat:betty

dog:frank

fish:george

goat:adam

2.4 基本知識點

1)Pattern Space:關于參數-n,表示取消預設輸出,相當于--quiet,--silent。在sed處理檔案的時候,每一行都被儲存在一個叫模式空間的臨時緩沖區中,除非行被删除或者輸出被取消,否則所有被處理的行都将列印在螢幕上。接着模式空間被清空,并存入新的一行等待處理。

2)Address:[address[,address]][!]{cmd},其中的!表示比對成功後是否執行指令,address可以是一個數字,也可以是一個模式,可以通過逗号分隔兩個address表示兩個address的區間。

3)指令打包:cmd可以是多個,它們可以用分号分開,可以用大括号括起來作為嵌套指令

對3行到第6行,比對/This/成功後,再比對/fish/,成功後執行d指令:

sed '3,6 {/This/{/fish/d}}' pets.txt

從第一行到最後一行,如果比對到This,則删除之;如果前面有空格,則去除空格:

sed '1,${/This/d ; s/^ *//g}' pets.txt

4)HoldSpace:保持空間

g:将hold space中的内容拷貝到pattern space中,原來pattern space裡的内容清除

G:将hold space中的内容append到pattern space\n後

h:将pattern space中的内容拷貝到hold space中,原來的hold space裡的内容被清除

H:将pattern space中的内容append到hold space\n後

x:交換pattern space和hold space的内容

sed -e '/test/h' -e '$G‘  example:在這個例子裡,比對test的行被找到後,将存入模式空間,h指令将其複制并存入一個稱為保持緩存區的特殊緩沖區内。第二條語句的意思是,當到達最後一行後,G指令取出保持緩沖區的行,然後把它放回模式空間中,且追加到現在已經存在于模式空間中的行的末尾。在這個例子中就是追加到最後一行。簡單來說,任何包含test的行都被複制并追加到該檔案的末尾。

sed -e '/test/h' -e '/check/x' example:互換模式空間和保持緩沖區的内容。也就是把包含test與check的行互換。

5)執行sed腳本:sed -f test.sed

末尾不能有任何空白或文本,如果在一行中有多個指令,要用分号分隔。以#開頭的行為注釋行,且不能跨行。

ps: 去除空白行:sed '/^ *$/d' file

3 sort:文本内容排序

語  法:sort [-bcdfimMnr] [-o<輸出檔案>] [-t<分隔字元>] [+<起始欄位>-<結束欄位>] [--help] [--verison] [檔案]

參  數:

-b    忽略每行前面開始出的空格字元。

-c    檢查檔案是否已經按照順序排序。

-d    排序時,處理英文字母、數字及空格字元外,忽略其他的字元。

-f    排序時,将小寫字母視為大寫字母。

-i    排序時,除了040至176之間的ASCII字元外,忽略其他的字元。

-m    将幾個排序好的檔案進行合并。

-M    将前面3個字母依照月份的縮寫進行排序。

-n    依照數值的大小排序。

-o<輸出檔案>    将排序後的結果存入指定的檔案。

-r    以相反的順序來排序。

-t<分隔字元>    指定排序時所用的欄位分隔字元。

+<起始欄位>-<結束欄位>    以指定的欄位來排序,範圍由起始欄位到結束欄位的前一欄位。

--help    顯示幫助。

--version    顯示版本資訊

4 uniq:Filter adjacent matching lines from INPUT (or standard input), writingto OUTPUT (or standard output)

顯示唯一的行,對于那些連續重複的行隻顯示一次,以及計數重複的行

uniq:不加任何參數表示比對第一次出現的那行

uniq -c:顯示重複的行的行數

uniq -u:僅顯示檔案中沒有連續出現的行,唯一行

uniq -d:僅顯示檔案中連續重複出現的行。

5 cut:片段颉取工具,可以從一個文本檔案或者文本流中提取文本列

5.1 指令用法

cut -b list [-n] [file ...]        

cut -c list [file ...]

cut -f list [-d delim][-s][file ...]

-b、-c、-f分别表示位元組、字元、字段(即byte、character、field);list表示-b,-c,-f操作範圍,-n表示具體數字,with -b: don’t split multibyte characters;file表示的自然是要操作的文本檔案的名稱;delim(英文全寫:delimiter)表示分隔符,預設情況下為TAB;-s表示不包括那些不含分隔符的行(這樣有利于去掉注釋和标題)。--output-delimiter=字元串,使用指定的字元串作為輸出分界符,預設采用輸入的分界符。上面三種方式中,表示從指定的範圍中提取位元組(-b)、或字元(-c)、或字段(-f)。

LIST的範圍:

N 隻有第N項
N- 從第N項一直到行尾
N-M 從第N項到第M項(包括M)
-M 從一行的開始到第M項(包括M)
- 從一行的開始到結束的所有項

5.2 用法執行個體

颉取/etc/passwd檔案中的前十五個使用者名:

cut -f1 -d: /etc/passwd | head -15

颉取/etc/passwd檔案每一行前十個位元組的内容:

cut -b 1-10 /etc/passwd

颉取該檔案每一行第1,4,7個位元組的内容:

cut -b 1,4,7 /etc/passwd

将/etc/passwd的分隔符換成“|”輸出:

cut -d: -f 1- -s --output-delimiter=”|” /etc/passwd

6 grep:颉取具有特定資訊的行,逐行操作

用法:grep [-acinv] [--color=auto] '搜尋字元串' filename

-a :    将binary檔案以text 檔案的方式搜尋資料

-c:    計算找到'搜尋字元串'的次數

-i:    忽略大小寫的不同,是以大小寫視為相同

-n :    順便輸出行号

-v :    反向選擇,亦即顯示出沒有'搜尋字元串'内容的那一行!

--color=auto:    可以将找到的關鍵詞部分加上顔色的顯示!

7 wc:wordcount,printnewline, word, and byte counts for each file

用法:wc [-lwmc]

-l :    僅列出行;    

-w :    僅列出多少字(英文單字); 

-m :    多少字元;

-c:    多少位元組

不加任何參數表示全部列出。

執行個體:/etc/man.config 裡面有多少相關字、行、字元數: