shell編程基礎(七): 處理文件命令sed與awk

一、sed(以行為單位處理文件)

  sed意為流編輯器(Stream Editor),在Shell腳本和Makefile中作為過濾器使用非常普遍,也就是把前一個程序的輸出引入sed的輸入,經過一系列編輯命令轉換為另一種格式輸出。sed和vi都源于早期UNIX的ed工具,所以很多sed命令和vi的末行命令是相同的。

0、sed命令格式

sed命令行的基本格式為:

sed option 'script' file1 file2 ...
sed option -f scriptfile file1 file2 ...

選項含義:

--version              顯示sed版本。
--help                 顯示幫助文檔。
-n,--quiet,--silent    靜默輸出,默認情況下,sed程序在所有的腳本指令執行完畢后,將自動打印模式空間中的內容,這些選項可以屏蔽自動打印。
-e script              允許多個腳本指令被執行。
-f script-file, 
--file=script-file     從文件中讀取腳本指令,對編寫自動腳本程序來說很棒!
-i,--in-place          直接修改源文件,經過腳本指令處理后的內容將被輸出至源文件(源文件被修改)慎用!
-l N, --line-length=N   該選項指定l指令可以輸出的行長度,l指令用于輸出非打印字符。
--posix                禁用GNU sed擴展功能。
-r, --regexp-extended   在腳本指令中使用擴展正則表達式
-s, --separate         默認情況下,sed將把命令行指定的多個文件名作為一個長的連續的輸入流。而GNU sed則允許把他們當作單獨的文件,這樣如正則表達式則不進行跨文件匹配。
-u, --unbuffered       最低限度的緩存輸入與輸出。

以上僅是sed程序本身的選項功能說明,至于具體的腳本指令(即對文件內容做的操作)后面我們會詳細描述,這里就簡單介紹幾個腳本指令操作作為sed程序的例子。

a,append        追加
i,insert        插入
d,delete        刪除
s,substitution  替換

如:在輸出testfile內容的第二行后添加"mmzs":

[root@VM_0_5_centos test]# cat testfile 
mmzs
mmzsblog
mmzsit
[root@VM_0_5_centos test]#  sed "2a mmzs" ./testfile
mmzs
mmzsblog
mmzs
mmzsit
//刪除2-5行后,輸出刪除后的結果
[root@VM_0_5_centos test]# sed "2,5d" testfile
mmzs

sed處理的文件既可以由標準輸入重定向得到,也可以當命令行參數傳入,命令行參數可以一次傳入多個文件,sed會依次處理。

sed的編輯命令可以直接當命令行參數傳入,也可以寫成一個腳本文件然后用-f參數指定,編輯命令的格式為:

/pattern/action
注:其中pattern是正則表達式,action是編輯操作

sed程序一行一行讀出待處理文件,如果某一行與pattern匹配,則執行相應的action,如果一條命令沒有pattern而只有action,這個action將作用于待處理文件的每一行。

1、常用的sed命令

/pattern/p  打印匹配pattern的行
/pattern/d 刪除匹配pattern的行
/pattern/s/pattern1/pattern2/ 查找符合pattern的行,將該行第一個匹配pattern1的字符串替換為pattern2
/pattern/s/pattern1/pattern2/g 查找符合pattern的行,將該行所有匹配pattern1的字符串替換為pattern2

使用p命令需要注意,sed是把待處理文件的內容連同處理結果一起輸出到標準輸出的,因此p命令表示除了把文件內容打印出來之外還額外打印一遍匹配pattern的行。例如:

一個文件testfile的內容是:
[root@VM_0_5_centos test]# cat testfile 
mmzs
mmzsblog
mmzsit
abc
123
打印其中包含abc的行
[root@VM_0_5_centos test]# sed '/abc/p' testfile
mmzs
mmzsblog
mmzsit
abc
abc
123
要想只輸出處理結果,應加上-n選項,這種用法相當于grep命令
[root@VM_0_5_centos test]# sed -n '/abc/p' testfile
abc
使用d命令就不需要-n參數了,比如刪除含有abc的行
[root@VM_0_5_centos test]# sed '/abc/d' testfile
mmzs
mmzsblog
mmzsit
123

注意:sed命令不會修改原文件,刪除命令只表示某些行不打印輸出,而不是從原文件中刪去。

使用查找替換命令時,可以把匹配pattern1的字符串復制到pattern2中,例如:

[root@VM_0_5_centos test]# sed 's/bc/-&-/' testfile
mmzs
mmzsblog
mmzsit
a-bc-
123
pattern2中的&表示原文件的當前行中與pattern1相匹配的字符串
再比如:
[root@VM_0_5_centos test]# sed 's/\([a-z]\)\([a-z]\)/-\1-~\2~/' testfile
-m-~m~zs
-m-~m~zsblog
-m-~m~zsit
-a-~b~c
123
pattern2中的\1表示與pattern1的第一個()括號相匹配的內容,\2表示與pattern1的第二個()括號相匹配的內容。

注意:sed默認使用Basic正則表達式規范,如果指定了-r選項則使用Extended規范,那么()括號就不必轉義了。

[root@VM_0_5_centos test]#  sed  's/yes/no/;s/mm/MM/'  ./testfile
注:使用分號隔開指令。
    
[root@VM_0_5_centos test]# sed -e 's/yes/no/' -e 's/mm/MM/' testfile
注:使用-e選項。

2、練習:

如果testfile的內容是:

<html><head><title>Hello World</title></head>
<body>Welcome to the world of mmzs!</body></html>

現在要去掉所有的HTML標簽,使輸出結果為:

Hello World
Welcome to the world of mmzs!

怎么做呢?如果用下面的命令:

[root@VM_0_5_centos test]# sed 's/<.*>//g' testfile

結果是兩個空行,把所有字符都過濾掉了。這是因為,正則表達式中的數量限定符會匹配盡可能長的字符串,這稱為貪心的(Greedy)。比如sed在處理第一行時,<.*>匹配的并不是或這樣的標簽,而是:

<html><head><title>Hello World</title>

這樣一整行,因為這一行開頭是<,中間是若干個任意字符,末尾是>。那么這條命令怎么改才對呢?答案如下:

錯誤:得到兩個空行,匹配過多
[root@VM_0_5_centos test]# sed 's/<.*>//g' testfile限定了匹配的行
[root@VM_0_5_centos test]# sed '/Hello World/s/<[/ a-z]*>//g' testfile 
Hello World
<body>Welcome to the world of mmzs!</body></html>
不完美示例,因為{4,5}導致可擴展性差
[root@VM_0_5_centos test]# sed -r 's/<(\/)?[a-z]{4,5}>//g' testfile 
Hello World
Welcome to the world of mmzs!
正確示例0:
[root@VM_0_5_centos test]# sed 's/<[/ a-z]*>//g' testfile 
Hello World
Welcome to the world of mmzs!
正確示例1:
[root@VM_0_5_centos test]# sed 's/<[^>]*>//g' testfile 
Hello World
Welcome to the world of mmzs!

注:上面代碼中的紅色部分表示pattern1部分的匹配規則,此處的/也不表示轉義,是語法中的(有點類似分隔符的意思)

二、awk(以列為單位處理文件)

  sed以行為單位處理文件,awk比sed強的地方在于不僅能以行為單位還能以列為單位處理文件。awk缺省的行分隔符是換行,缺省的列分隔符是連續的空格和Tab,但是行分隔符和列分隔符都可以自定義,比如/etc/passwd文件的每一行有若干個字段,字段之間以:分隔,就可以重新定義awk的列分隔符為:并以列為單位處理這個文件。awk實際上是一門很復雜的腳本語言,還有像C語言一樣的分支和循環結構,但是基本用法和sed類似。

0、awk命令格式

awk命令行的基本形式為:

awk option 'script' file1 file2 ...
awk option -f scriptfile file1 file2 ...

和sed一樣,awk處理的文件既可以由標準輸入重定向得到,也可以當命令行參數傳入,編輯命令可以直接當命令行參數傳入,也可以用-f參數指定一個腳本文件,編輯命令的格式為:

/pattern/{actions}
condition{actions}
和sed類似,pattern是正則表達式,actions是一系列操作

解釋:awk程序一行一行讀出待處理文件,如果某一行與pattern匹配,或者滿足condition條件,則執行相應的actions,如果一條awk命令只有actions部分,則actions作用于待處理文件的每一行。

1、常用命令

比如文件testfile的內容表示某商店(產品-價格-銷量):

[root@VM_0_5_centos test]# cat testfile 
ProductA  30 13
ProductB  76 46
ProductC  55 32

打印每一行的第二列:

[root@VM_0_5_centos test]# awk '{print $2;}' testfile
30
76
55

自動變量$1、$2分別表示第一列、第二列等,類似于Shell腳本的位置參數,而$0表示整個當前行。再比如,如果某種產品的庫存量低于75則在行末標注需要訂貨:

[root@VM_0_5_centos test]# awk '$2<75 {printf "%s\t%s\n", $0, "REORDER";} $2>=75 {print $0;}' testfile
ProductA  30 13    REORDER
ProductB  76 46
ProductC  55 32    REORDER

可見awk也有和C語言非常相似的printf函數。awk命令的condition部分還可以是兩個特殊的condition-BEGIN和END,對于每個待處理文件,BEGIN后面的actions在處理整個文件之前執行一次,END后面的actions在整個文件處理完之后執行一次。

awk命令可以像C語言一樣使用變量(但不需要定義變量),比如統計一個文件中的空行數:

[root@VM_0_5_centos test]# cat testfile 
ProductA  30 13
ProductB  76 46ProductC  55 32
[root@VM_0_5_centos test]# awk '/^ *$/ {x=x+1;} END {print x;}' testfile
2

就像Shell的環境變量一樣,有些awk變量是預定義的有特殊含義的:

awk常用的內建變量:

FILENAME   當前輸入文件的文件名,該變量是只讀的
NR      當前行的行號,該變量是只讀的,R代表record
NF      當前行所擁有的列數,該變量是只讀的,F代表field
OFS     輸出格式的列分隔符,缺省是空格
FS      輸入文件的列分融符,缺省是連續的空格和Tab
ORS     輸出格式的行分隔符,缺省是換行符
RS      輸入文件的行分隔符,缺省是換行符

例如打印系統中的用戶帳號列表:

[root@VM_0_5_centos test]# awk 'BEGIN {FS=":"} {print $1;}' /etc/passwd
root
bin
daemon

?

轉載于:https://www.cnblogs.com/mmzs/p/9336906.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451911.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451911.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451911.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構與算法--6.二分查找

文章目錄一. 二分查找二. 代碼實現一&#xff1a;使用遞歸三. 代碼實現二&#xff1a;非遞歸一. 二分查找 二. 代碼實現一&#xff1a;使用遞歸 def binary_search(alist, item):"""二分查找&#xff1a;使用遞歸"""n len(alist)if n > 0:m…

SpringMVC請求處理流程、springMVC工作流程

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 頁面請求到來 --> 前端控制器&#xff08;DispatcherServlet&#xff09;收到請求&#xff0c;請求 處理映射器&#xff08;Hanle…

Android的TextView在顯示文字的時候,如果有段中文有英文,有中文,有中文標點符號,你會發現,當要換行的時候遇到中文標點, 這一行就會空出很多空格出來...

一、問題描述&#xff1a; Android的TextView在顯示文字的時候&#xff0c;如果有段中文有英文&#xff0c;有中文&#xff0c;有中文標點符號&#xff0c;你會發現&#xff0c;當要換行的時候遇到中文標點&#xff0c; 這一行就會空出很多空格出來。原因是&#xff1a; 1&…

什么是IDE

集成開發環境&#xff08;IDE&#xff0c;Integrated Development Environment &#xff09;是用于提供程序開發環境的應用程序&#xff0c;一般包括代碼編輯器、編譯器、調試器和圖形用戶界面等工具。集成了代碼編寫功能、分析功能、編譯功能、調試功能等一體化的開發軟件服務…

vue 學習

http://jspang.com/ vue 學習 vue 學習 轉載于:https://www.cnblogs.com/qianjin888/p/9342031.html

策略模式-Strategy Pattern

解決問題 將算法按照策略或場景封裝起來&#xff0c;以方便按照不同的場景執行不同的策略。它很好的解決了通過if...else 來決策行為而帶來的代碼和邏輯復雜性。 應用場景 一個經常被拿來舉例的場景是收銀員收銀場景&#xff1a;它需要根據不同的場景&#xff08;是否為會員、有…

ssm框架下 tiles框架 的使用

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 tiles框架的工作 在springMVC工作流程中屬于視圖解析器 解析視圖這一步。算是視圖解析器的一個插件&#xff0c;作了視圖解析這步的一部…

數據結構與算法--7.樹的基礎知識

文章目錄一. 樹的概念二. 樹的術語三. 樹的種類四. 樹的存儲和表示五. 常見的樹的應用場景一. 樹的概念 二. 樹的術語 三. 樹的種類 四. 樹的存儲和表示 五. 常見的樹的應用場景

運用java 多線程模擬火車售票。。。。

public class Demo01 { public static void main(String[] args) { // TODO Auto-generated method stub //多線程并行時&#xff0c;會出現的問題 //同步&#xff1a; //買火車票&#xff0c;四個窗口A,B,C,D //創建任務 TicketTask task new TicketTask(); //四個窗口A,B,C,…

JQuery validate 各項驗證規則講解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 使用樣例見&#xff1a;http://blog.csdn.net/jiangyu1013/article/details/56014730 //定義中文消息 var cnmsg { required: “必選字…

數據結構與算法--8.二叉樹的基礎知識

文章目錄一. 二叉樹基本概念二. 二叉樹的性質三. 二叉樹的代碼實現四. 二叉樹的先序、中序、后序遍歷一. 二叉樹基本概念 二. 二叉樹的性質 三. 二叉樹的代碼實現 class Node(object):"""二叉樹節點"""def __init__(self,item):self.elem item…

ZooKeeper(二)ZooKeeper能做什么?

上一節介紹了ZooKeeper的一些基礎知識&#xff0c;這一節主要講ZooKeeper有哪些用途。命名服務&#xff08;Name Service&#xff09; 主要是作為分布式命名服務&#xff0c;通過調用zk的create node api&#xff0c;能夠很容易創建一個全局唯一的path&#xff0c;這個path就可…

jquery vilidate 使用小例

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 // 修改$("#updForm").validate({submitHandler:function(form){new $.flavr({ content : 是否確認修改管理員?,dialog : co…

RedHat Linux 7.3基礎環境搭建

文章目錄1&#xff0e;更改主機名2&#xff0e;關閉selinux3&#xff0e;關閉火墻4&#xff0e;重啟機器5&#xff0e;設置ip6&#xff0e;掛載yum源7&#xff0e;升級openssh8&#xff0e;安全基線9&#xff0e;時區10&#xff0e;時間同步11&#xff0e;安裝Vmtools12&#x…

開源http協議庫curl和wget的區別和使用

curl和wget基礎功能有諸多重疊&#xff0c;如下載等。 在高級用途上的curl由于可自定義各種請求參數所以長于模擬web請求&#xff0c;用于測試網頁交互&#xff08;瀏覽器&#xff09;&#xff1b;wget由于支持ftp和Recursive所以長于下載&#xff0c;用于下載文件&#xff08;…

Spring聲明式事務管理、事務的傳播行為xml配置

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. <tx:method name"insert*" propagation"REQUIRED" />中name的值是ServiceImpl中各個要加入事物管理的方法…