linux三劍客之sed命令

来源:http://www.cnblogs.com/0zcl/archive/2017/05/16/6855740.html
-Advertisement-
Play Games

一、前言 我們都知道,在Linux中一切皆文件,比如配置文件,日誌文件,啟動文件等等。如果我們相對這些文件進行一些編輯查詢等操作時,我們可能會想到一些vi,vim,cat,more等命令。但是這些命令效率不高,這就好比一塊空地準備搭建房子,請了10個師傅拿著鐵鍬挖地基,花了一個月的時間才挖完,而另外 ...


 

一、前言

我們都知道,在Linux中一切皆文件,比如配置文件,日誌文件,啟動文件等等。如果我們相對這些文件進行一些編輯查詢等操作時,我們可能會想到一些vi,vim,cat,more等命令。但是這些命令效率不高,這就好比一塊空地準備搭建房子,請了10個師傅拿著鐵鍬挖地基,花了一個月的時間才挖完,而另外一塊空地則請了個挖土機,三下五除二就搞定了,這就是效率。而在linux中的“挖土機”有三種型號:頂配awk,中配sed,標配grep。使用這些工具,我們能夠在達到同樣效果的前提下節省大量的重覆性工作,提高效率。

sed 是Stream Editor(字元流編輯器)的縮寫,簡稱流編輯器。什麼是流?大家可以想象以下流水線,sed就像一個車間一樣,文件中的每行字元都是原料,運到sed車間,然後經過一系列的加工處理,最後從流水線下來就變成貨物了。

編輯文件也是這樣,以前我們修改一個配置文件,需要移動游標到某一行,然後添加點文字,然後又移動游標到另一行,註釋點東西.......可能修改一個配置文件下來需要花費數十分鐘,還有可能改錯了配置文件,又得返工。這還是一個配置文件,如果數十個數百個呢?因此當你學會了sed命令,你會發現利用它處理文件中的一系列修改是很有用的。只要想到在大約100多個文件中,處理20個不同的編輯操作可以在幾分鐘之內完成,你就會知道sed的強大了。

 

二、軟體功能與版本

Sed命令是操作,過濾和轉換文本內容的強大工具。常用功能有增刪改查(增加,刪除,修改,查詢),其中查詢的功能中最常用的2大功能是過濾(過濾指定字元串),取行(取出指定行)。

我們現在準備學習的sed版本是GNU開源版本

[root@chengliang mail]# sed --version
GNU sed version 4.2.1

  

三、命令執行流程

Sed軟體從文件或管道中讀取一行,處理一行,輸出一行;再讀取一行,再處理一行,再輸出一行....

一次一行的設計使得sed軟體性能很高,sed在讀取非常龐大的文件時不會出現卡頓的想象。大家都用過vi命令,用vi命令打開幾十M或更大的文件,會發現有卡頓現象,這是因為vi命令打開文件是一次性將文件載入到記憶體,然後再打開,因此卡頓的時間長短就取決於從磁碟到記憶體的讀取速度了。而且如果文件過大的話還會造成記憶體溢出現象。Sed軟體就很好的避免了這種情況,打開速度非常快,執行速度也很快。

現有一個文件person.txt,共有五行文本,sed命令讀入文件person.txt的第一行“101,chensiqi,CEO”,並將這行文本存入模式空間(sed軟體在記憶體中的一個臨時緩存,用於存放讀取到的內容,比喻為工廠流水線的傳送帶。)

文件person.txt在模式空間的完整處理流程

  • 判斷第1行是否是需要處理的行,如果不是要處理的行就重新從文件讀取下一行,如果是要處理的行,則接著往下走。
  • 對模式空間的內容執行sed命令,比如a(追加),i(插入),s(替換)...
  • 將模式空間中經過sed命令處理後的內容輸出到屏幕上,然後清空模式空間
  • 讀取下一行文本,然後重新執行上面的流程,直到文件結束

sed是非互動式的編輯器。它不會修改文件,除非使用shell重定向來保存結果。預設情況下,所有的輸出行都被列印到屏幕上。 sed編輯器逐行處理文件(或輸入),並將結果發送到屏幕。具體過程如下:首先sed把當前正在處理的行保存在一個臨時緩存區中(也稱為模式空間),然後處理臨時緩衝區中的行,完成後把該行發送到屏幕上。sed每處理完一行就將其從臨時緩衝區刪除,然後將下一行讀入,進行處理和顯示。處理完輸入文件的最後一行後,sed便結束運行。sed把每一行都存在臨時緩衝區中,對這個副本進行編輯,所以不會修改原文件。  

Sed軟體有兩個內置的存儲空間:

  • 模式空間(pattern space):是sed軟體從文本讀取一行文本然後存入的緩衝區(這個緩衝區是在記憶體中的),然後使用sed命令操作模式空間的內容。
  • 保持空間(hold space):是sed軟體另外一個緩衝區,用來存放臨時數據,也是在記憶體中,但是模式空間和保持空間的用途是不一樣的。Sed可以交換保持空間和模式空間的數據,但是不能在保持空間上執行普通的sed命令,也就是說我們可以在保持空間存儲數據。

 

四、使用規範文本

[root@chengliang zcl]# cat zcl.txt
[root@chengliang zcl]# cat > zcl.txt <<KOF
> 101,chengliang,aa
> 102,alex,bb
> 103,eric,cc
> 104,laonanhai,dd
> KOF
[root@chengliang zcl]# cat zcl.txt
101,chengliang,aa
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

KOF必須成對出現,表示終止輸入

命令說明:使用一條cat命令創建多行文本,文件包含上面的內容,後面的操作都會使用這個文件。

 

五、常用功能-增刪改查

1、增

比如我們平時往配置文件寫入幾行文本,最常用的是vi或vim命令,但是這2個命令是一種互動式的命令,還需要我們在vi/vim編輯器界面輸入字元串然後保存退出,操作有些繁瑣但是還能用。但是當我們學會了Shell腳本後,我們就會發現在腳本中不能正常使用vi或vim命令,為什麼呢?同學們請自行體驗。

這裡我們需要用到2個sed命令,分別是:

  • “a”:追加文本到指定行後,記憶方法:a的全拼是apend,意思是追加。
  • “i“:插入文本到指定行前,記憶方法:i的全拼是insert,意思是插入。

在文件中增加一行文本,我們以前學過echo命令可以在文件的末尾追加文本,比較簡單,但是我們還有其他的複雜需求,比如在第10行插入一行數字等等,這裡就需要sed出馬了。

[root@chengliang zcl]# sed "2a hahaha" zcl.txt
101,chengliang,aa
102,alex,bb
hahaha  #新增的那句
103,eric,cc
104,laonanhai,dd

引號的區別總結

sed使用的過程中用單引號還是雙引號?這裡給大家詳細說說引號的區別。

[root@chengliang zcl]# cat zcl.txt
101,chengliang,aa
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# sed '2i $PATH' zcl.txt     #單引號--文本內容原封不動插入
101,chengliang,aa
$PATH
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# sed "2i $PATH" zcl.txt    #雙引號--變數$PATH被解析以後在當作文本進行插入
101,chengliang,aa
/application/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# sed 2i $PATH zcl.txt    #不加引號,linux無法辨認空格,不會把有空格的命令當成一條命令來執行
sed: -e expression #1, char 2: expected \ after `a', `c' or `i'
[root@chengliang zcl]# 

總結:

  • 如果引號裡面是普通字元串的話,你可以任意使用單引號或者雙引號:
  • 如果引號裡面是變數或者帶反引號的命令的話,你想要變數解析的結果或者命令執行的結果,那就使用雙引號;你想要引號內的原樣字元串,那就使用單引號。

添加多行文本

-e     enable interpretation of backslash escapes    //啟用反斜杠轉義解釋

[root@chengliang zcl]# echo "zcl";echo "zcl"
zcl
zcl
[root@chengliang zcl]# echo "zcl\nzcl"      
zcl\nzcl
[root@chengliang zcl]# echo -e "zcl\nzcl"
zcl
zcl
[root@chengliang zcl]# 

命令說明:這裡就“\n”派上用場了,行與行之間是以“\n”作為分隔符的,所以“chensiqi\nchensiqi”就等效於2行chensiqi。接下來我們用echo命令實驗一下,其中-e參數表示字元串中如果出現以下特殊字元(\n代表換行,\t代表Tab鍵等),則加以特殊處理,而不會將它當成一般文字輸出。

[root@chengliang zcl]# sed "2a wawawa\nhahaha" zcl.txt
101,chengliang,aa
102,alex,bb
wawawa
hahaha
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

當然還有另外一種方法添加多行文本,但這種方法並沒有“\n”方便,所以在這裡就簡單說一下。這種方法利用了“\”,它也有換行的意思。如果大家在執行一行很長的命令時候,如果都寫在一行,那太難看了也難以理解,因此就利用到了這個符號可以將一條完整的命令分成多行,舉個例子:

[root@chengliang zcl]# echo my \        
> name\
> is \
> zcl
my nameis zcl
[root@chengliang zcl]# 

sed命令使用反斜線,首先輸入完“sed '2a 106,dandan,CSO \”,然後敲回車鍵,這樣視窗會顯示一個符號“>”,我們在這個符號後面接著寫命令的剩餘部分“107,bingbing,CCO‘ person.txt”。

[root@chengliang zcl]#  sed '2a 106,dandan,CSO \
> 107,bingibng,CCO' \  
> zcl.txt
101,chengliang,aa
102,alex,bb
106,dandan,CSO 
107,bingibng,CCO
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

sed軟體使用命令i插入多行文本和命令和a的用法是一樣的,因此這裡不再詳細列出,大家可以練習一下

 

企業案例1:優化SSH配置(一鍵完成增加若幹參數

在我們學習CentOS6系統優化時,有一個優化點:更改ssh服務遠程登錄的配置。主要的操作是在ssh的配置文件/etc/ssh/sshd_config加入下麵5行文本。

Port 52113    #ssh服務埠
PermitRootLogin no    #不允許root遠程登陸
PermitEmptyPasswords no    #不允許密碼為空
UseDNS no
GSSAPIAuthentication no

當然我們可以使用vi/vim命令編輯這個文本,但是這樣就比較麻煩,現在想用一條命令增加5行文本到第13行前?

[root@chengliang ~]# sed -i '13i Port 52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNS no\nGSSAPIAuthentication no' /etc/ssh/sshd_config

命令說明:題目要求在第13行前插入,那就需要使用命令13i。有同學做個題目時,是這樣想的,在13行前,那不就是12行後嗎,12a也是可以的。是的,這樣也是沒錯的,這可以算是第二種方法。
最後插入的5行內容使用“\n”就可以變成一行了。
上面還有一個沒講過的選項"-i",這個選項能夠實際的修改文件內容,大家練習時可以去掉,防止改掉了配置文件。如果使用了-i,可以用備份文件還原。當然,在生產環境修改配置文件那就需要用-i選項了。
[root@chensiqi1 ~]# sed -n '13,17p' /etc/ssh/sshd_config
Port 52113
PermitRootLogin no
PermitEmptyPasswords no
UseDNS no
GSSAPIAuthentication no

 

刪除指定行文本

地址範圍含義
10{sed-commands} 對第10行操作
10,20{sed-commands} 對10到20行操作,包括第10,20行
10,+20{sed-commands} 對10到30(10+20)行操作,包括第10,30行
1~2{sed-commands} 對1,3,5,7.....行操作
10,\${sed-commands} 對10到最後一行($代表最後一行)操作,包括第10行
/chensiqi/{sed-commands} 對匹配chensiqi的行操作
/chensiqi/,/Alex/{sed-commands} 對匹配chensiqi的行到匹配Alex的行操作
/chensiqi/,\${sed-commands} 對匹配chensiqi的行到最後一行操作
/chensiqi/,10{sed-commands} 對匹配chensiqi的行到第10行操作,註意:如果前10行沒有匹配到chensiqi,sed軟體會顯示10行以後的匹配chensiqi的行
1,/Alex/{sed-commands} 對第1行到匹配Alex的行操作
/chensiqi/,+2{sed-commands} 對匹配chensiqi的行到其後的2行操作

如果在sed命令前面不指定地址範圍,那麼預設會匹配所有行,然後使用d命令刪除功能就會刪除這個文件的所有內容

[root@chengliang zcl]# cat test.txt  
welcome to my blog:http://www.cnblogs.com/0zcl

if you like my blog\'s contents,please support me!


bye! boys and girls.
[root@chengliang zcl]# sed "d" test.txt
[root@chengliang zcl]# 

單行刪除想必大家能理解,指定刪除第2行的文本102,alex,bb

[root@chengliang zcl]# sed "2d" zcl.txt
101,chengliang,aa
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

"2,3d" 指定刪除第2行到第3行的內容,d代表刪除操作。

[root@chengliang zcl]# sed "2,3d" zcl.txt
101,chengliang,aa
104,laonanhai,dd
[root@chengliang zcl]#

  

正則匹配刪除

上面我們實驗完了數字地址範圍,接下來我們實驗一下正則表達式的地址範圍,雖然說可以使用正則表達式,但是我們還是習慣寫出完整的匹配字元串,達到精確匹配的目的。

在sed軟體中,使用正則的格式和awk一樣,使用2個”/“包含指定的正則表達式,即“/正則表達式/”"/alex/d"有哪一行有alex則刪除這一行

[root@chengliang zcl]# sed "/alex/d" zcl.txt
101,chengliang,aa
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

這是正則表達式形式的多行刪除,也是以逗號分隔2個地址,最後結果是刪除包含“alex”的行到包含“eric”的行

[root@chengliang zcl]# sed "/alex/,/eric/d" zcl.txt
101,chengliang,aa
104,laonanhai,dd
[root@chengliang zcl]# 

學過正則表達式後我們知道“$”代表行尾,但是在sed中就有一些變化了,“$”在sed中代表文件的最後一行。因此本例子的含義是刪除第2行到最後一行的文本,包含第2行和最後一行,因此只剩下第1行的內容。

[root@chengliang zcl]# sed "2,$d" zcl.txt
sed: -e expression #1, char 2: unexpected `,'
[root@chengliang zcl]# sed "2,\$d" zcl.txt
101,chengliang,aa
[root@chengliang zcl]# sed '2,$d' zcl.txt    
101,chengliang,aa
[root@chengliang zcl]# 

在工作中我們最常用的還是數字地址這種精確匹配方式,像上面的正則地址或混合地址這種模糊匹配用的比較少,瞭解即可。

具體可參考: http://www.cnblogs.com/chensiqiqi/p/6382080.html

 

特殊符號~(步長)解析

格式:“First~step”表示從開始,以步長step遞增,這個在數學中叫做等差數列

例子:

  • 1~2 匹配1,3,5,7.....#-->用於只輸出奇書行,大伙仔細觀察一下每個數字的差值。
  • 2~2 匹配2,4,6,8....#-->用於只輸出偶數行
  • 1~3 匹配1,4,7,10.....
  • 2~3 匹配2,5,8,11.....
[root@chengliang zcl]# seq 10
1
2
3
4
5
6
7
8
9
10
[root@chengliang zcl]# seq 10 | sed -n "1~2p"
1
3
5
7
9
[root@chengliang zcl]# 

命令說明:seq命令能夠生成從1到10的數字序列

命令說明:上面的命令主要驗證特殊符號“~”的效果,其他sed命令用法n和p請見後文詳解,大家只需要知道這個命令可以將“1~2”指定的行顯示出來即可。

如果大家想生成奇數數列,其實上面的方法是為了舉例,並不是一個很好的方法,因為seq命令自帶這種功能

[root@chengliang zcl]# seq 1 2 10
1
3
5
7
9
[root@chengliang zcl]# 

命令說明:seq命令格式seq起始值 公差 結束值

[root@chengliang zcl]# sed "1~2d" zcl.txt
102,alex,bb
104,laonanhai,dd
[root@chengliang zcl]# sed "1,+2d" zcl.txt
104,laonanhai,dd
[root@chengliang zcl]# 

命令說明:“1~2”這是指定行數的另一種格式,從第1行開始以步長2遞增的行(1,3,5),因此刪掉第1,3,5行,即所有的奇數行。

命令說明:這其實是做個加法運算,1,+2d’==>刪除第1行到第3(1+2)行的文本

[root@chengliang zcl]# sed '2,3!d' zcl.txt
102,alex,bb
103,eric,cc
[root@chengliang zcl]# 

命令說明:在地址範圍“2,3”後面加上“ !”,如果不加“!”表示刪除第2行和第3行,結果如下麵的例子所示,然後加上“!”的結果就是除了第2行和第3行以外的內容都刪除,這個方法可以作為顯示文件的第2,3行題目的補充方法。

 

按行替換,這個功能用的很少,所以大家瞭解即可。這裡用到的sed命令是:
“c”:用新行取代舊行,記憶方法:c的全拼是change,意思是替換。

[root@chengliang zcl]# sed "2c wahaha" zcl.txt
101,chengliang,aa
wahaha
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

命令說明:使用sed命令c將原來第2行 “102,alex,bb” 替換成 “wahaha” , 整行替換

 

文本替換

有工作經驗的同學應該非常的熟悉,因為使用sed軟體80%的場景就是使用替換功能

這裡用到的sed命令,選項:(重要)

  • “s”:單獨使用-->將每一行中第一處匹配的字元串進行替換==>sed命令
  • “g”:每一行進行全部替換-->sed命令s的替換標誌之一(全局替換),非sed命令。
  • “-i”:修改文件內容-->sed軟體的選項,註意和sed命令i區別。

sed軟體替換模型  ===>  sed -i 's#目標內容#替換內容#g'

  • 定界符/或#,第一個和第二個之間的就是被替換的內容,第二個和第三個之間的就是替換後的內容。建議大家使用#作為定界符。
  • s#目標內容#替換內容#g ,“目標內容”能用正則表達式,但替換內容不能用,必須是具體的。因為替換內容使用正則的話會讓sed軟體無所適從,它不知道你要替換什麼內容。
  • 預設sed軟體是對模式空間(記憶體中的數據)操作,而-i選項會更改磁碟上的文件內容

結果為第二行的“bb”替換為“i am bb”。

[root@chengliang zcl]# sed "s#bb#i am bb#g" zcl.txt              
101,chengliang,aa
102,alex,i am bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

[root@chensiqi1 ~]# sed -i 's#zhangyang#dandan#g' person.txt

命令說明:如果想真正的修改文件內容,我們就需要使用選項“-i”。同時我們可以發現命令執行後的結果是沒有任何輸出的。

 

企業案例2:指定行修改配置文件

[root@chengliang zcl]# sed "3s#0#9#" zcl.txt
101,chengliang,aa
102,alex,bb
193,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

命令說明: 前面學習的例子在sed命令“s”前沒有指定地址範圍,因此預設是對所有行進行操作。 而這個案例要求只將第3行的0換成9,這裡就用到了我們前面學過的地址範圍知識,在sed命令“s”前加上“3”就代表對第3行進行替換

 

變數替換

變數替換其實和前面的文本替換是一樣的,就是具體的文本變成了變數,同時要求大家對引號的用法要有清晰的理解.

[root@chengliang zcl]# cat > person.txt<<KOF 
> a
> b
> a
> KOF
[root@chengliang zcl]# cat person.txt
a
b
a
[root@chengliang zcl]# x=a
[root@chengliang zcl]# y=b
[root@chengliang zcl]# echo $x    ##-->設置變數x並 賦值a
a
[root@chengliang zcl]# echo $b

[root@chengliang zcl]# echo $y
b
[root@chengliang zcl]# 

不使用引號

[root@chengliang zcl]# sed s#$x#$y#g person.txt
b
b
b
[root@chengliang zcl]# sed 's#'$x'#'$y'#g' person.txt
b
b
b
[root@chengliang zcl]# sed 's#$x#$y#g' person.txt
a
b
a
[root@chengliang zcl]#
命令說明:錶面看起來單引號是可以用的,但其實這裡用了障眼法,在你們眼中分段‘$x’和'$y',但其實分段是‘s#’和‘#’和‘#g’,所以$x和$y並沒有被引號擴起來,和上面的例子就一樣了。

使用eval命令:

[root@chengliang zcl]# sed 's#$x#$y#g' person.txt  
a
b
a
[root@chengliang zcl]# eval sed 's#$x#$y#g' person.txt  
b
b
b
[root@chengliang zcl]# 

命令說明:這裡給大家擴展一個Linux內置命令eval,這個命令能讀入變數,並將他們組合成一個新的命令,然後執行。首先eval會解析變數$x和變數$y,最後達到的效果和雙引號是一樣的

拓展: 最快速的獲取IP地址的方法

[root@chengliang zcl]# hostname -I 
192.168.179.133 
[root@chengliang zcl]# 

 

分組替換()和\1的使用說明

sed軟體的()的功能可以記住正則表達式的一部分,其中,\1為第一個記住的模式即第一個小括弧中的匹配內容,\2第二個記住的模式,即第二個小括弧中的匹配內容,sed最多可以記住9個。

例:echo "I am chensiqi teacher."  如果想保留這一行的單詞chengliang,刪除剩下部分,使用圓括弧標記想保留的部分。

[root@chengliang zcl]# echo "I am chengliang student." | sed 's#^.*am \([a-z]\+\) stu.*$#\1#g' 
chengliang
[root@chengliang zcl]# echo "I am chengliang student." | sed -r 's#^.*am ([a-z]+) stu.*$#\1#g'   
chengliang
[root@chengliang zcl]# echo "I am chengliang student." | sed -r 's#I (.*) (.*) stu.*$#\1#g'                   
am
[root@chengliang zcl]# echo "I am chengliang student." | sed -r 's#I (.*) (.*) stu.*$#\1\2#g'
amchengliang
[root@chengliang zcl]# 

再來看個題目:請執行命令取出linux中的eth0的IP地址?

[root@chensiqi1 ~]# ifconfig eth0 | sed -n '2p'
          inet addr:192.168.197.133  Bcast:192.168.197.255  Mask:255.255.255.0
[root@chensiqi1 ~]# ifconfig eth0 | sed -n '2p' | sed -r 's#^.*addr:(.*) Bcast:.*$#\1#g'
192.168.197.133

也可以進行組合

[root@chensiqi1 ~]# ifconfig eth0 | sed -rn '2s#^.*addr:(.*) Bcast:.*$#\1#gp'
192.168.197.133 

命令說明:
這道題是需要把ifconfig eth0執行結果的第2行的IP地址取出來,上面答案的思路是用IP地址來替換第2行的內容。

 

特殊符號&代表被替換的內容

這是一個特殊技巧,在適合的場景使用特別方便。下麵用特殊符號“&”與分組替換一起使用,進行對比。

[root@chengliang zcl]# cat zcl.txt
101,chengliang,aa
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# sed -r 's#(.*),(.*),(.*)#& ----- \1 \2 \3#' zcl.txt 
101,chengliang,aa ----- 101 chengliang aa
102,alex,bb ----- 102 alex bb
103,eric,cc ----- 103 eric cc
104,laonanhai,dd ----- 104 laonanhai dd
[root@chengliang zcl]# 

上面命令的&符號代表每一行,即模型中‘s#目標內容#替換內容#g’的目標內容。

 

企業案例3:批量重命名文件

當前目錄下有文件如下所示:

[root@chengliang test_1]# find ./ -name "*_finished.jpg"
./stu_102999_4_finished.jpg
./stu_102999_1_finished.jpg
./stu_102999_5_finished.jpg
./stu_102999_3_finished.jpg
./stu_102999_2_finished.jpg
[root@chengliang test_1]#

要求用sed命令重命名,效果為:

stu_102999_1_finished.jpg==>stu_102999_1.jpg,即刪除文件名的_finished
mv - move (rename) files

解題思路:因為這是文件名,不能直接yongsed命令替換,因此還需要藉助mv命令重命名

格式為:mv stu_102999_1_finished.jpg stu_102999_1.jpg. 我們需要拼湊這樣的格式,然後使用bash命令執行即可。

[root@chengliang test_1]# find ./ -name "*_finished.jpg" | sed -r 's#^(.*)_finished(.*)#\1\2#g'
./stu_102999_4.jpg
./stu_102999_1.jpg
./stu_102999_5.jpg
./stu_102999_3.jpg
./stu_102999_2.jpg
[root@chengliang test_1]# find ./ -name "*_finished.jpg" | sed -r 's#^(.*)_finished(.*)#mv & \1\2#g' 
mv ./stu_102999_4_finished.jpg ./stu_102999_4.jpg
mv ./stu_102999_1_finished.jpg ./stu_102999_1.jpg
mv ./stu_102999_5_finished.jpg ./stu_102999_5.jpg
mv ./stu_102999_3_finished.jpg ./stu_102999_3.jpg
mv ./stu_102999_2_finished.jpg ./stu_102999_2.jpg
[root@chengliang test_1]# find ./ -name "*_finished.jpg" | sed -r 's#^(.*)_finished(.*)#mv & \1\2#g' | bash
[root@chengliang test_1]# ls
stu_102999_1.jpg  stu_102999_2.jpg  stu_102999_3.jpg  stu_102999_4.jpg  stu_102999_5.jpg
[root@chengliang test_1]# 

命令說明:

  1. “\1”代表前面“(^.*)”匹配內容,“&”代表“s# #”里被替換的內容,這裡匹配到的是完整的文件名。
  2. 使用bash命令執行,bash命令執行標準輸入的語句,如同我們在命令行輸入語句後敲回車。

 

我們想查看文件中的某些行,以前最常用的是cat或more或less命令等,但這些命令有些缺點,就是不能查看指定的行。而我們用了很久的sed命令就有了這個功能了。而且我們前面也說過使用sed比其他命令vim等讀取速度更快!

“p”:輸出指定內容,但預設會輸出2次匹配的結果,因此使用-n選項取消預設輸出,記憶方法:p的全拼是print,意思是列印。

按行查詢

[root@chengliang zcl]# sed "2p" zcl.txt
101,chengliang,aa
102,alex,bb
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# sed -n "2p" zcl.txt
102,alex,bb
[root@chengliang zcl]# 
命令說明:選項-n取消預設輸出,只輸出匹配的文本,大家只需要記住使用命令p必用選項-n。

[root@chengliang zcl]# sed -n "2,3p" zcl.txt
102,alex,bb
103,eric,cc
[root@chengliang zcl]# 
命令說明:查看文件的第2行到3行,使用地址範圍“2,3”。取行就用sed,最簡單

[root@chengliang zcl]# sed -n "1~2p" zcl.txt
101,chengliang,aa
103,eric,cc
命令說明:列印文件的1,3,5行。~代表步長

[root@chengliang zcl]# sed -n "p" zcl.txt
101,chengliang,aa
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 
命令說明:不指定地址範圍,預設列印全部內容。

按字元串查詢

[root@chengliang zcl]# sed -n "/alex/p" zcl.txt    ==>命令說明:列印含CTO的行
102,alex,bb
[root@chengliang zcl]# 
[root@chengliang zcl]# sed -n "/alex/,/chengliang/p" zcl.txt
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# sed -n "/alex/,/eric/p" zcl.txt    ==>命令說明:列印含alex的行到含eric的行
102,alex,bb
103,eric,cc
[root@chengliang zcl]# 

混合查詢

[root@chengliang zcl]# sed -n "2, /cc/p" zcl.txt
102,alex,bb
103,eric,cc
命令說明:列印第2行到含cc的行。

[root@chengliang zcl]# sed -n "/cc/,2p" zcl.txt
103,eric,cc
[root@chengliang zcl]# 
命令說明:特殊情況,前兩行沒有匹配到cc,就向後匹配,如果匹配到cc就列印此行。所以這種混合地址不推薦使用。

 過濾多個字元

[root@chengliang zcl]# sed -rn "/alex|cc/p" zcl.txt
102,alex,bb
103,eric,cc
[root@chengliang zcl]# 

命令說明: 使用擴展正則“|”,為了不使用轉義符號“\”,因此使用-r選項開啟擴展正則表達式模式

 

sed修改文件的同時進行備份

[root@chengliang zcl]# ls
a  a.bak  ac  ae  ae.bak  afff  person.txt  test.txt  test_1  zcl.txt
[root@chengliang zcl]# sed -i.bak "s#chengliang#Fuck#g" zcl.txt
[root@chengliang zcl]# ls
a  a.bak  ac  ae  ae.bak  afff  person.txt  test.txt  test_1  zcl.txt  zcl.txt.bak
[root@chengliang zcl]# cat zcl.txt
101,Fuck,aa
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# cat zcl.txt.bak
101,chengliang,aa
102,alex,bb
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

命令行說明: 在-i參數的後邊加上.bak(.任意字元),sed會對文件進行先備份後修改

 

特殊符號=獲取行號

[root@chengliang zcl]# sed '=' zcl.txt
1
101,Fuck,aa
2
102,alex,bb
3
103,eric,cc
4
104,laonanhai,dd
命令說明:使用特殊符號“=”就可以獲取文件的行號,這是特殊用法,記住即可。從上面的命令結果我們也發現了一個不好的地方:行號和行不在一行。

[root@chengliang zcl]# sed '1,3=' zcl.txt
1
101,Fuck,aa
2
102,alex,bb
3
103,eric,cc
104,laonanhai,dd
命令說明:只列印1,2,3行的行號,同時列印輸出文件中的內容

[root@chengliang zcl]#
[root@chengliang zcl]# sed '/alex/=' zcl.txt
101,Fuck,aa
2
102,alex,bb
103,eric,cc
104,laonanhai,dd
命令說明:只列印正則匹配行的行號,同時輸出文件中的內容

[root@chengliang zcl]# sed -n '/alex/=' zcl.txt
2
命令說明:只顯示行號但不顯示行的內容即取消預設輸出

[root@chengliang zcl]# sed -n '$=' zcl.txt
4
[root@chengliang zcl]# 
命令說明:“$”代表最後一行,因此顯示最後一行的行號,變相得出文件的總行數。

方法改進:

[root@chengliang zcl]# sed '=' zcl.txt | sed 'N;s#\n# #'      
1 101,Fuck,aa
2 102,alex,bb
3 103,eric,cc
4 104,laonanhai,dd
[root@chengliang zcl]# 

  

sed如何取不連續的行

[root@chengliang zcl]# sed -n "1p;3p;4p" zcl.txt
101,Fuck,aa
103,eric,cc
104,laonanhai,dd
[root@chengliang zcl]# 

特殊符號{}的使用

[root@chengliang zcl]# sed -n '2,3p;=' zcl.txt 
1
102,alex,bb
2
103,eric,cc
3
4
[root@chengliang zcl]# sed -n '2,3{p;=}' zcl.txt
102,alex,bb
2
103,eric,cc
3
[root@chengliang zcl]# 
  • 命令說明:-n去掉預設輸出,2,4p,輸出2到4行內容,=輸出全部的行的行號
  • 命令說明: ‘2,4{p;=}’代表統一輸出2,4行的行號和內容

 

參考博客: http://www.cnblogs.com/chensiqiqi/p/6382080.html

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HDFS 架構簡述 Hadoop分散式文件系統(HDFS)是一個分散式的文件系統,運行在廉價的硬體上。它與現有的分散式文件系統有很多相似之處。然而與其他的分散式文件系統的差異也是顯著的。HDFS是高容錯的,被設計成在低成本硬體上部署。HDFS為應用數據提供高吞吐量的訪問,適用於具有大規模數據集的應用 ...
  • 一、關聯分析的基本概念 關聯分析(Association Analysis):在大規模數據集中尋找有趣的關係。 頻繁項集(Frequent Item Sets):經常出現在一塊的物品的集合。 關聯規則(Association Rules):暗示兩個物品之間可能存在很強的關係。 支持度(Support ...
  • 如果想在一臺電腦上搭建一個多節點的Hadoop集群,傳統的方式是使用多個虛擬機。但這種方式占用的資源比較多,一臺筆記本能同時運行的虛擬機的數量是很有限的。這個時候我們可以使用Docker。Docker可以看做是一種輕量級的虛擬機,占用資源少,用起來和傳統的虛擬機很像,使用的時候可以類比VMware或 ...
  • " 1、觸發器理論 " "1.1、觸發器的應用場景" "1.2、觸發器的類型" "1.3、DML 觸發器的觸發順序" " 2、觸發器實戰 " "2.1、創建觸發器" "2.1.1、創建 DML 觸發器" "2.1.2、創建 DDL 觸發器" "2.1.3、創建事件觸發器" "2.2、調試觸發器" " ...
  • 系統環境: Linux-centOS+ubuntu 操作: 編輯允許通過IP 路徑:vim /etc/hosts.allow 編輯禁止通過IP 路徑:vim /etc/hosts.deny 重啟網路服務 以上。 IP限制往往搭配代理伺服器混合使用,目的是比安全更安全! 代理伺服器相關搭建及配置【點擊 ...
  • 線程:線程是進程中的執行單元,也是分配CPU的最小單元。 組成部分:線程棧和內核對象 線程棧是存儲線程所需的資源。 內核對象是操作系統中的私有結構塊,通過它去管理當前的線程。 結束方式:強制殺死或者自然退出 同一進程中的多個線程退出:用變數的方式。 不同進程中多個線程的退出:跨進程操作,用消息和事件 ...
  • #! /bin/bash #設置只讀變數,只讀變數不可修改myUrl="http://www.baidu.com"readonly myUrl #刪除變數,unset不能刪除只讀變數myUrl1="http://www.sina.com"unset myUrl1 #運行shell時會同時存在三種變數 ...
  • 1.最近新學習websocket。做了一個實時聊天。用Node.js搭建的服務:serevr.js. 兩個相互通信頁面:client.html 和server.html 但是就是有很多問題,想讓知道的人幫我看看哈: 我先把代碼貼出來: server.js: var ws=require("nodej ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...