linux sed给空文件首行插入_Sed命令高级功能,学好了工作不愁
原創(chuàng):小姐姐味道(微信公眾號ID:xjjdog),歡迎分享,轉(zhuǎn)載請保留出處。
sed命令有兩個空間,一個叫pattern space,一個叫hold space。這兩個空間能夠證明人類的腦瓜容量是非常小的,需要經(jīng)過大量的訓(xùn)練和燒腦的理解,才能適應(yīng)一些非常簡單的操作。
不信看下面簡單的命令,作用是,刪除文件中最后兩行。
sed 'N; $!P;$!D;$d' file在
《Linux生產(chǎn)環(huán)境上,最常用的一套“Sed“技巧》
一文中,我們介紹了常用的sed命令和操作,而且使用了兩張圖來作為輔助。但可惜的是,這兩張圖,嚴格來說是不準確的 (比如s命令,只是其中的一個子集),即使它能夠幫助初學者快速入門。
本篇屬于sed的中級用法,常見在一些sed腳本中,在日常中應(yīng)用并不多,但往往能夠獲得意想不到的效果。
原理
工作模式
這要從sed的工作模式來說起。
按照我們讀取一個文件的尿性,一般是持續(xù)循環(huán)讀取。比如下面的python代碼,print代表p命令。
with open('file', 'r') as f: for line in f.readlines(): print(line)sed命令在這之上,還緩沖了另外一個東西。那就是“上一行的內(nèi)容” ,叫做hold space。而當前行,叫做patter space。用python簡單表現(xiàn)一下:
hold_space = ""with open('file', 'r') as f: for pattern_space in f.readlines(): print(hold_space,pattern_space) hold_space = pattern_space具體過程,大體與上面的代碼類似,以上面的圖為例。在這個例子中,hold space不參與運算,是全程無感的:
1、 讀取當前行 wtf.. 到 Pattern space
2、 執(zhí)行命令p,這會打印出當前行
3、 把Pattern space的內(nèi)容,賦值給Hold space
4、 繼續(xù)下一行的處理,循環(huán)這個過程
一個例子:x
但我想稍微操作一下這兩個緩沖區(qū)。這個操作就是swap,使用x表示,這也是一些文本編輯器的一貫?zāi)蛐浴?/p>
也就是,在p之前,我們加上了個x。表示先將這兩個緩沖區(qū)進行置換,然后再往下走。
hold_space = ""with open('file', 'r') as f: for pattern_space in f.readlines(): swap(hold_space,pattern_space) print(hold_space,pattern_space) hold_space = pattern_space讓我我們來想象一下這個過程。
1、 剛開始,hold_space的內(nèi)容是空。然鵝,還沒被填充,它就被使用了,和當前行進行了置換
2、 p命令用在了置換后的緩沖區(qū)上,第一次打印出了空行,fuck
3、 繼續(xù)嘟嘟嘟,現(xiàn)在到了最后一行,馬上進行了置換,沒機會打印就到了hold_space中了
4、 當前行,存放的是倒數(shù)第二行的數(shù)據(jù),最后一行見光死,就永遠沒有機會面世了
我們當然有辦法把它搞出來,比如,我執(zhí)行偶數(shù)次的交換x。
sed -n 'x;x;x;x;p' file有木有一股騎著羊駝走天下的的感覺?
應(yīng)用
舉個栗子
你可能會想,我對這兩個緩沖區(qū)交換,有什么用?接下來看這個文件。
小姐姐味道公眾號CEO加菲貓經(jīng)理IT Manager系統(tǒng)毀滅師Sysadmin小哥哥味道Developer愛賣東西的經(jīng)理Sales Manager風清揚Dog文件奇數(shù)行是名稱,偶數(shù)行是職位。我們想要輸出所有Manager的名字。就可以使用下面的命令。
sed -n -e 'x;n' -e '/Manager/{x;p}' file命令分為兩個部分。
x;n 表示將偶數(shù)行保存在pattern space,那么奇數(shù)行就保存在hold space中。
/Manager/{x;p} 命令將在pattern space上執(zhí)行對Manager關(guān)鍵字的查找。如果符合條件,則再次交換p和h緩沖區(qū),輸出奇數(shù)行對應(yīng)的名字。
上面的x和n,就是針對這兩個緩沖區(qū)的命令。這樣的命令有很多。
命令
這些命令,如果多了,可以使用{}包圍起來,就像上面的命令一樣。這些命令的位置與我們上一篇所說的,在同一個地方。
常用的:
x 請容許我用英文裝個b:Exchange the contents of the hold and pattern spaces.
d 清空當前的pattern space,然后進入下一個循環(huán)
D 刪除pattern space的第一行(multiline pattern)
h 復(fù)制pattern space到hold space
H 追加pattern spaced到hold space
g 復(fù)制hold space到pattern space
G 追加hold space到pattern space
n 讀取下一個輸入行到pattern space
N 追加下一個輸入行到pattern space,同時將兩行看做一行,但是兩行之間依然含有換行符
p 打印當前的pattern space
P 打印當前的pattern space中的第一行
不常用的
上次提到的推箱子游戲,就用了很多這種東西。為了使使用者在書寫sed腳本的時候真正的”自由”,sed還允許在腳本中用”:”設(shè)置記號。標簽,有種類似編程語言的特性了。
q 退出sed,可以增加執(zhí)行速度
l 列出當前行,包含不可打印字符
l width 列出當前行,使用一個width characters結(jié)尾
b label 跳到相應(yīng)的標簽,分之命令。
t label if分支,從最后一行開始,條件一旦滿足或者T,t命令,將導(dǎo)致分支到帶有標號的命令處,或者到腳本的末尾。測試命令。
T label 錯誤分支,從最后一行開始,一旦發(fā)生錯誤或者T,t命令,將導(dǎo)致分支到帶有標號的命令處,或者到腳本的末尾。
當然還有其他更不常用的,可以使用man命令查看
man sed一些命令:開啟訓(xùn)練模式
看著一行行進行處理,好像很簡單是不是?不可能的,看下面幾個簡單的命令,訓(xùn)練一下生銹的腦子。
一個流水線一樣的命令
sed -n '2{h;n;x;H;x};p' file交換第2行和第3行的內(nèi)容
輸出最后一行
sed 'N;D' file輸出文件中最后兩行
sed '$!N; $!D' file刪除文件中最后兩行
sed 'N; $!P;$!D;$d' file打印偶數(shù)行的另一種寫法
sed –n 'n;p' file每隔5行加入一個空行。
sed 'n;n;n;n;G' file輸出含AAA和BBB和CCC(任意順序)的段落
sed -e '/./{H; $!d;}' -e 'x;/AAA/!d; /BBB/!d; /CCC/!d' file顛倒行序(使末行變首行,首行變末行)
sed -n '1!G; h; $p' file這個命令有點繞,首先,1!G對除了第一行的其他行進行了G操作,然后反向復(fù)制回去,到了最后一行,就直接打印Pattern Space。$表示到了最后一行執(zhí)行下面的命令,也可以是${p}
一個帶標簽的用法
sed -e :a -e '$q;N;11,$D;ba'打印最后10行。a是標簽。語法就是單獨的行,使用:分隔。
End
為了提高你在公司的競爭力,你是可以弄一堆sed腳本唬人(埋雷)的。和某些perl腳本一樣,即使是有相關(guān)經(jīng)驗的開發(fā)著,理解起來也要下點功夫,就不要說其他人了。
這就是sed,簡約但不簡單的命令,本文算是一個中級入門。中級入門也有點燒腦,因為你的腦瓜里,需要一直維護著這兩個緩沖區(qū)。又是置換,又是清空,相當于人肉狀態(tài)機。當然,怎么把這個過程講的盡量簡單一點,還是浪費了作者不少腦細胞的。哪怕你點個贊,也是延緩小姐姐走向老年癡呆時間的一個途徑。有了你的支持,小姐姐也可以想點技術(shù)之外的事情,比如噴噴bat什么的。
作者簡介:小姐姐味道(xjjdog),一個不允許程序員走彎路的公眾號。聚焦基礎(chǔ)架構(gòu)和Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。我的個人微信xjjdog0,歡迎添加好友,?進一步交流。?
總結(jié)
以上是生活随笔為你收集整理的linux sed给空文件首行插入_Sed命令高级功能,学好了工作不愁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绿盟数据库审计系统hive_数据库审计系
- 下一篇: linux 其他常用命令