標籤:each text 檔案的 .text 排序 運算式 count 決定 display
以下工具的使用都是建立在會簡單使用Regex的基礎上,不瞭解的群攻自己做功課。
sed
sed是一種流式編輯器,是一種文本編輯工具,以行為單位進行文本操作。sed預設按照basic規則進行匹配。
常用的命令格式如下:
sed option ‘/pattern/action‘ file
pattern:為一個Regex,用來匹配所要操作的字串行。
action:是操作方法。常用的操作方法有:
- p,將匹配到的內容列印兩次,其他未匹配的列印一次。
- d,將匹配到的字串刪除。
- s,進行匹配字元替換。常用黨的命令格式如下:
sed option ‘patter/s/patter1/patter2/g’ file
在patter匹配的字串行中,用patter2替換patter1。加g選項是全部替換,不加g選項只替換第一個匹配到的。
- n,讀取下一行到模式緩衝區中,將模式空間的原內容清空。
- N,讀取檔案的下一行追加到模式空間內,不請客原內容。
option:選項,對資料做的相應操作,常用的有:
- -n 將匹配到的字串行輸出,其他不輸出。
- -i 將修改的內容同步修改到源檔案。
- -e 多項編輯命令,可串連多個sed指令對同一行進行操作。
定址
定址用於決定對哪些行進行編輯。地址的表示可以由數字,Regex或者二者的結合。如果沒有指定地址,sed將處理輸入檔案的每一行。
eg:
sed -n ‘3p’ file 列印檔案第三行。
sed -n ‘100,200p’ file 列印檔案第100行~200行的資訊。
地址是逗號分隔的,需要處理的地址是這兩行之間的範圍(包括這兩行在內)。範圍可以用數組Regex或者二者的結合表示。
sed ‘2,5d’ file 刪除第2行到底5行
sed ‘/start/,/end/d’ file 刪除包含‘start’行和‘end’行之間的行。
sed ‘/start/,10d’ file
模式空間
sed對一個檔案進行操作時,會依次將檔案的每一行拷貝讀取到一個特殊的緩衝區,也叫模式空間內,依次讀取一行。讀取完後進行Regex的匹配,若匹配,則進行action操作,若不匹配則丟棄。緊接著處理完後讀取下一行。所以sed對檔案行的操作是在模式空間內,不會對源檔案進行修改。
保持空間
我們可以把保持空間想象成一個倉庫,作為資料的暫存地區,但記住,處理資料時依然需要將資料由保持空間載入到模式空間。
保持空間並不常用,只有以下幾條指令會用到保持空間。
g:將保持空間的內容拷貝到模式空間內,並將模式空間的原內容清除。
G:將保持空間的內容追加到模式空間內,不清除原內容。
h:將模式空間的內容拷貝到保持空間,將原來保持空間的內容清除。
H:將模式空間的內容追加到保持空間,不清除原內容。
d:刪除模式空間的所有行,並讀入下一新行到模式空間。
D:刪除multiline pattern的第一行,不讀入下一行。
x:交換保持空間與模式空間的內容。
eg:
①給檔案的末尾加一個空行
②將檔案逆序輸出(類比tac指令)
③將匹配的行追加到檔案尾。
sed -e ‘/hello/H‘ -e ‘$G‘ file ###類似於複製功能
sed -e ‘/hello/{H;d}‘ -e ‘$G‘ file ## 類似於剪下功能
④行列轉換
sed -n ‘H;{x;s/\n/ /g;p}‘ file
模式空間預設去掉每一行的\n,所以要想僅僅在模式空間內部將\n替換掉是行不通的, 保持空間內部有兩行或兩行以上內容時,會在每一行後面加上\n,所以現將資料Hold到保持空間,在執行x指令,進行模式空間與保持空間內容的交換,再進行替換。
⑤求1~100的和
seq 100|sed -n ‘H;${x;s/\n/+/g;s/^+//;p}‘|bc ### bc指令是對錶達式求和。
s/^+// 表示將開頭多餘的加號替換為空白。
⑥讀取奇偶行
這裡用到了n命令,讀取下一行到模式空間。
sed -n ‘p;n‘ file ### 讀取奇數行sed -n ‘n;p‘ file ### 讀取偶數行
標籤
定義一個標籤:
:a ### 定義標籤規則為冒號加標籤名,例標籤名為a
跳轉到標籤:b+標籤名
ba ### 跳轉到標籤a
再次實現1到100求和:
sed -n ‘:a;N;s/\n/+/g;{!ba};p‘ ####!ba 表示最後一行不跳轉到標籤a
N實現的是將下一行追加到模式空間的功能,如第一次執行語句是,將1讀入模式空間,此時執行N將下一行追加到模式空間,此時模式空間的內容就變成1\n2,再進行+號的替換,依次類推,直到最後一行。
awk
awk既是一種文本分析工具,也是一種指令碼語言。作為一種文本分析工具,它的功能比grep或者sed要強大的多,但它的用法與sed類似。作為一種指令碼語言,它與c語言文法類似,有與c語言一樣的分支和迴圈結構,是一種類c語言。
相對於sed來說,awk強大的地方在於它既可以以行為單位進行文本編輯,又可以以列為單位進行文本編輯。awk預設的預設的行分隔字元為換行\n,預設的資料行分隔符號為連續的空格或者tab。比如:
除了以空格和tab作為分隔字元外,還可以自訂分隔字元,如用冒號做分隔字元。
當以列為單位時,$0表示整行的內容,$1表示第一列…$n表示第n列。
awk命令列的格式:
awk option ‘/pattern/{action}‘ fileawk option -f scriptfile file ### 用 -f 指定指令檔
pattern為Regex,用於匹配要操作的行。action為要執行的動作。
這裡要說一個-F選項,-F選項可以指定輸入欄位分隔字元,當我們在檔案內使用自己指定的分隔字元時,預設的awk指令是識別不了的,我們需要用-F選項指定出我們需要辨識的分隔字元。如我們在上面用的分隔字元是冒號‘:’,下面我要列印第二列的內容:
awk ‘{print $2;}‘ file ### 失敗,系統無法辨識分隔字元。
-F:
awk -F: ‘{print $2;}‘ file ### 成功,指定分隔字元為:
Regex
利用Regex進行行匹配:
①找出productC的行的內容:
②尋找編號為2(第三列,以2結尾)的內容:
指定域進行Regex匹配。~與!~
可以用~指定固定的域(列)進行正則匹配。!~與~!相同。與if語句搭配使用。
①找出第二列中以1開頭的資料行。
awk -F: ‘{if($2 ~ /^1/){print $0;}}‘ file
②找出第二列中不以1開頭的資料行。
awk -F: ‘{if ($2 !~ /^1/){print $0}}‘ file
條件匹配
除了用Regex進行行匹配外,還可以進行條件匹配,命令格式如下:
awk option ‘condition{action}‘ file
如:將第二列的值小於100的都標記為NO,其他標記為YES。
awk -F: ‘$2<100{print $0,"NO";}$2>100{print $0,"YES";}‘ file
注意{}裡面的寫法,逗號‘,’作為輸出域分隔字元,在輸出時被轉化為空白格。
BEFIN和END
要理解BEGIN和END,先要理解awk執行的三個過程,分別為,文本處理之前,文本處理中,文本處理之後。
BEGIN就是文本處理之前執行的動作,END就是文本處理之後執行的動作。
eg:利用BEGIN和END計算行數。
awk -F: ‘BEGIN{x=0}{print $0;x++}END{print "total:",}‘
BEGIN,END可單獨使用可搭配使用。如下:單獨使用END輸出行號。
我們在上面說過,awk也是一種類c語言,是一種弱類型語言,它的變數不需要定義,可直接使用,下例中x預設初值為 0。
awk指令碼
awk除了上述以命令列方式使用外,還可以以shell指令碼的方式使用。因為awk也是一種指令碼語言,所以awk有有自己的命令直譯器,/bin/awk或者/bin/awk -f。
test.awk:
#!/bin/awk -fBEGIN{ count1=0; //注意變數的定義格式 count2=0; count3=0; total=0;}{ print $0; if($2 < 100){ count1++; }else if($2 >= 100 && $2 < 200){ count2++; }else if($2 >= 200){ count3++; }total++;}END{ printf("<100: %d\n",count1); ### 類c語言,可直接使用printf。 printf(">=100 && < 200: %d\n",count2); printf(">=200: %d\n",count3); printf("total: %d\n",total);}
awk指令檔的調用格式為:
awk [-F+分隔字元] -f awkfile file
例:
awk -F: -f test.awk file
執行結果為:
awk的內建變數
ARGC 命令列參數的個數ENVIRON 支援隊列中系統內容變數的使用FILENAME awk瀏覽的檔案名稱FNR 瀏覽檔案中的記錄數(行數)FS 設定輸入欄位分隔字元,等價於命令列 -F選項NF 瀏覽記錄的域的個數NR 已讀的記錄數OFS 輸出域分隔字元ORS 輸出記錄分隔字元RS 控制記錄分隔字元
printf與print
awk是類c語言,所以在指令碼程式或者命令列都可以使用printf。有時使用printf可以使輸出格式變得更加工整。
eg:
awk -F: ‘{printf("filename:%s count:%d data:%s\n",FILENAME,FNR,$0)}‘ file
結果:
[[email protected] ~]$ awk -F: ‘{printf("filename:%s count:%d data:%s\n",FILENAME,FNR,$0)}‘ filefilename:file count:1 data:productA:123:1filename:file count:2 data:productB:22:2filename:file count:3 data:productC:23:3filename:file count:4 data:productD:3:4filename:file count:5 data:productE:223:5
練習:統計目錄下普通檔案所佔用的位元組數
ls -lR | grep -E ‘^-‘| awk ‘{print $9,$5;total+=$5}END{print total}‘
結果:
除此之外,還可以用find指令來尋找對應大小的檔案,但無法求和。
find . -size +100c -a -size -1000c -exec ls -l {} \;
cut
cut的功能是‘剪’,以行為單位進行文本處理。命令格式如下:
選項主要有三個:
-b:按照位元組進行切割。
-c:按字元進行切割
-b與-c的區別在於,-b無法剪下中文,而一個中文也算一個字元,所以-c可以剪下中文。相對於英文字元來說,它們兩個功能相同。
-f 按域進行剪下。與-d搭配使用,-d指定分隔字元,-f指定域。
sort
sort的功能是對指定的檔案按照一定的規則進行排序。格式為:
sort option file
1、單獨使用sort預設以字元的ACCIS碼的值進行排序。
2、-u ,按照字元ACCIS碼以升序排序,並去掉重複的行。
3、-r ,逆序排序
4、sort file -o file ,排序並修改源檔案。
5、-n 按照數值大小進行排序。
6、按照指定的列進行排序,-t 指定分隔字元,-k指定列數。
7、-f,將小寫字母轉換為大寫字母進行比較,即忽略大小寫。
8、-c 檢測檔案是否已排好序,如果亂序,則輸出第一個亂序的行的相關資訊,最後返回1。
9、檢查檔案是否已排好序,如果亂序,不輸出內容,僅返回1。
10,-M 按照月份來排序
11、-b,忽略每一行前面的空白部分,從第一個可見字元開始比較。
eg:
[lzk@localhost ~]$ cat filegoogle 110 5000baidu 100 5000guge 50 3000sohu 100 4500
1、按照第二列人數進行排序。
[lzk@localhost ~]$ sort -t‘ ‘ -k 2n fileguge 50 3000baidu 100 5000sohu 100 4500google 110 5000
2、按照人數排序,當人數相同時,按照第三列工資進行排序。
[lzk@localhost ~]$ sort -t‘ ‘ -k 2n -k 3n fileguge 50 3000sohu 100 4500baidu 100 5000google 110 5000
3、按照公司名稱第二個字母開始往後進行比較(即按照第一個域的第2個字母直到本域結束)
[lzk@localhost ~]$ sort -t‘ ‘ -k 1.2 filebaidu 100 5000sohu 100 4500google 110 5000guge 50 3000
4、僅按照公司名稱的第二個字母進行排序,如果相同,按照員工人數進行排序。
因為僅按照第一列的第二個字母進行排序,所以用1.2,1.2的方式表示,2,2表示只按照第2個域進行排序,如果唯寫一個2,則表示按照第2個域到最後一個域進行排序。
[lzk@localhost ~]$ sort -t‘ ‘ -k 1.2,1.2 -k 2,2n filebaidu 100 5000sohu 100 4500google 110 5000guge 50 3000
uniq
這個命令讀取輸入檔案,並比較相鄰的行,在正常情況下,第二個以後以後更多個重複的行將被山區,行比較是根據所用字元集的排序序列進行的。該命令加工後的結果寫到輸出檔案中。輸入檔案和輸出檔案必須統統。如果輸入檔案用‘-’表示,則從標準輸入讀取。
常用的選項如下:
-c:去掉連續的重複行,並在每行行首加上本行重複出現的此時。可以取代-u或者-d選項。
-d:只顯示重複行。
-u:只顯示檔案中不重複的行。
Linux常用文本編輯工具及常用指令