打开高效文本编辑之门_熟悉Linux Sed的替换命令
? ? ? ? ? ? ? ? ? ? ? ? ? ? Linux sed S替換命令常見使用案例
聲明與簡介
sed:Stream Editor文本流編輯,sed是一個“非交互式的”面向字符流的編輯器。本文主要以實際的數據來介紹sed的substitude(替換)即s命令的使用。
替換是工作中經常用的應用場景,比如在拼接較多表的SQL命令時,即可通過sed的S命令進行字符的替換以達到拼接字符串的目的。S命令即是刪除行 (substitude)是對sed的輸出流里的數據進行替換而不是直接作用到文件本身。
注: 1 至少有一臺linux環境,當前驗證環境是Centos 8。
? ? ? ? 2 了解常見的linux腳本的寫法,能認識或者常用單詞的縮寫。
? ? ? ? 3 本文會根據實際實踐更新和修正,歡迎批評、指導。
? ? ? ? 4?還不過癮?傳送門鏈接將至,歡迎點擊查閱其它博文:? ??
? ? ? ? ? ? ? ? 1?sed模擬常見文件命令案例
? ? ? ? ? ? ? ? 2?sed 寫命令常見案例
? ? ? ? ? ? ? ? 3?sed 刪除行命令案例
? ? ? ? ? ? ? ? 4?sed 打印模式空間p命令案例
? ? ? ? ? ? ? ? 5?sed插入追加轉換退出等命令案例
? ? ? ? ? ? ? ? 6?sed命令執行方式匯總案例
一般形式為
sed '[address-range|pattern-range] s/original-string/replacement-string/[substitute-flags]' inputfile
- address-range 是文本的范圍(行起始位置)
- pattern-range 是匹配的范圍(行起始位置)
- s是固定關鍵字
- original-string是文本的原始內容,即原有關鍵字(字符串)
- replacement-string是要替換成的字符串
- substitute-flags 是替換標識(選項)
數據說明
如下是使用的示例文本數據,這里的行號是為了方便解釋結果,不是文本內容。
1 7369,smith,clerk,7902,'1980-12-17',800,null,20 2 7499,allen,salesman,7698,'1981-2-20',1600,300,30 3 7521,ward,salesman,7698,'1981-2-22',1250,500,30 4 7566,jones,manager,7839,'1981-4-2',2975,null,20 5 7654,martin,salesman,7698,'1981-9-28',1250,1400,30 6 7655,jack,manager,7698,'1987-3-28',1600,1800,10 7 7656,tim,clerk,7902,'1982-12-12',1400,1400,30 8 7657,kate,clerk,7902,'1989-11-11',1400,1800,10 9 7698,blake,manager,7839,'1981-5-1',2850,null,30 10 7699,dlake,salesman,7839,'1983-6-15',3000,null,10 11 7782,clark,manager,7839,'1981-1-9',2450,null,10 12 7788,scott,analyst,7566,'1982-12-9,3000,null,20 13 7839,king,president,null,'1981-11-17',5000,null,10 14 7844,turner,salesman,7698,'1981-12-8',1500,0,30 15 7876,adams,clerk,7788,'1983-1-12',1100,null,20 16 7900,james,clerk,7698,'1981-12-3',950,null,30 17 18 --7902,ford,analyst,7566,'1981-12-3',3000,null,20 19 20 7934,miller,clerk,7782,'1982-1-23',1300,null,10替換文本內容
局部替換每行關鍵字(僅首次)
# 1 用word2替換word1,該方式只會替換word1首次出現。 sed 's/word1/word2/' filename# 示例 用null替換unkown sed 's/null/unknow/' emp.txt#以下內容僅摘錄更改部分的數據,完整的數據未附錄。忽略大小寫關鍵字行替換
# 2 用word2替換word1,該方式只會替換word1首次出現同時忽略大小寫。 sed 's/word1/word2/i' filename# 示例 用null替換unkown sed 's/null/unknow/i' emp.txt全局替換每行關鍵字
# 3 用word2替換word1,g參數會在word1出現的所有位置替換。 sed 's/word1/word2/g' filename# 示例 用mg替換manager sed 's/null/unkown/g' emp.txt# 對比示例1的結果不難發現,加了g選項后,該行里的所有的null都被替換成了unknow,而不是僅僅第一次出現的null。指定重復出現位次替換
# 4 將每行里第m此出現的word1替換為word2。 # 這里n的范圍是1到512。 # 如果word1的出現次數小于m,那么替換不生效。sed 's/word1/word2/m' filename # 示例 用將每行里第二次出現的null替換為unkonw. sed 's/null/unkown/2' emp.txt#替換部分的結果見下: 7839,king,president,null,'1981-11-17',5000,unkown,10匹配關鍵字行替換
# 5 對文件內出現word1關鍵字的行里的word2用word3替換。 sed '/word1/s/word2/word3/' filename# 示例 將含有jack的行里的manager用mg替換 sed '/jack/s/manager/mg/' emp.txt # 延展,同理如果word2出現多次,想要全部替換,想要加上g選項。即命令如: sed '/jack/s/manager/mg/g' emp.txt替換結合其它命令選項
替換結合控制臺打印
# 1刪除第n行,以m為步長(增幅)的所有行,輸出為剩下內容。這里~是波浪線。 sed 's/word1/word2/p' filename# 示例 用將每行里第二次出現的null替換為unkonw并將結果打印在控制臺上。 sed -n 's/null/unkown/2 p' emp.txt sed -n 's/null/unkown/2p' emp.txt # 結果見下: 7839,king,president,null,'1981-11-17',5000,unkown,10替換結合寫文件
# 2 文件infilename將關鍵字word1替換為word2并寫入文件outfilename內。 sed '/word1/word2/w outfilename' infilename# 刪除包含clerk和salesman的行,這里主要是借助|(管道符號)實現,即前面的輸出作sed -n 's/null/unknow/2w outfile.txt' emp.txt# cat outfile.txt 7839,king,president,null,'1981-11-17',5000,unknow,10替換結合執行選項
# 3 替換結合e選項,即替換后的文本是linux可執行命令,加e之后可以直接執行輸出結果。 # 文件filename_tmp.txt里有一行,內容是“emp”。 cat filename_tmp.txt # 內容為emp emp# 通過e選項,可以直接執行命令。 sed 's/^/ls -a|grep /e' filename_tmp.txt # 結果為 emp_bak.txt emp.txt多個選項合并使用
# 將多個選項結合在一起使用。# 示例,將每行里第2次出現的null替換為unkown,忽略大小寫,全局替換(即所有出現2次時),顯示在控制臺里、寫入文件outfile.txt內。 sed -n 's/null/unkonw/2gip w outfile.txt ' emp.txt# 結果 7839,king,president,null,'1981-11-17',5000,unknow,10使用轉義符
#我們在字符串替換時用的符號是/,那么如果文本內容里也有/,那么顯然是起沖突的。所以這是我們得用轉移字符\。這和我們在其它語言里常見的處理方式類同。# 將文件內的/替換為\,這里因為S的替換內含”/”了,所以想要用到轉移字符”\” cat filename_tmp.txt # 文件內容見下: /root/shenl/# 執行轉換 sed 's/\/root\/shenl\//\\root\\shenl\\/' filename_tmp.txt# 結果,如下。 \root\shenl\替換時自定義分隔符
#如果嫌轉義字符轉來轉去麻煩,也可以自定義替換里的分隔符,而不是用默認的”\”。 # 在替換命令s里自定義替換分隔符,這里用的@,也可以用|、!、^等特殊符號。前提是文本內不會出現該分隔符。 # 注意,這里指定的分隔符不支持多個字符,比如@|作為一個分隔符是不支持的。# 將文件內的/替換為\ #cat filename_tmp.txt# 文件內容 /root/shenl/# 這里因為\是轉義字符,所以想要加2個給轉回來。 sed 's@/root/shenl/@\\root\\shenl\\@' filename_tmp.txt # 結果 \rootshenl\批量替換
# 多個替換命令批量執行,執行時會按照順序執行,而不是并行執行。# 將sales替換為sale后再將man替換為woman。 sed '{ s/sales/sale/ s/man/woman/ }' emp.txt整文本打包替換
# 如果想將幾個匹配的模式打包成一個整體替換,可以用& #以數字正則匹配,將4個數字的作為一個整體“word”,在這個“word”前后加上雙引號“。 sed 's/^[0-9][0-9][0-9][0-9]/"&"/g' emp.txt# 執行結果部分示例數據見下: "7369",smith,clerk,7902,'1980-12-17',800,null,20 "7499",allen,salesman,7698,'1981-2-20',1600,300,30 "7521",ward,salesman,7698,'1981-2-22',1250,500,30#如果想頭和尾匹配則想要用到正則符號,^(頭)、$(尾)。 # 示例,在每行的開頭和結尾分別加上{和}。 sed 's/^.*$/{&}/g' emp.txt # 結果示例 {7369,smith,clerk,7902,'1980-12-17',800,null,20}單組方式匹配替換
#該方式對行按某個模式匹配,這里的模式可以認為是一種以字符串的分割或者前后有字符串的分割模式。比如以單字符;、|、:分割,或者已()、[]、{}前后分割。# 這里的單組的意思是只提取出一組。:cat file_tmp.txt # 結果 /usr/apps/bin:/usr/local/bin:/root/:/root/software /usr/local/sbin:/usr/apps/sbin:/opt/bin# 提取出第一組 # 1 這里是\([^:]*\) 是匹配所有字符(內容)直到”:”。# 2 \1指的是提取第1組。 sed 's/\(\/[^:]*\).*/\1/g' file_tmp.txt # 結果 /usr/apps/bin /usr/local/sbin# 提取出第二組 # 參數類似上例,這里有個匹配模式后的符號“:”要指定正確。sed 's/\([^:]*\):\([^:]*\):\(.*\).*/\2/g' file_tmp.txt #結果 /usr/local/bin /usr/apps/sbin多組方式匹配替換
# 多組的和單組的類似,主要是輸出時同對幾個組同時操作(同組重復也可以)。 cat file_tmp.txt #結果 /usr/apps/bin:/usr/local/bin:/root/ /usr/local/sbin:/usr/apps/sbin:/opt/bin# 不難發現此時group1和group3調換了位置,且組間以逗號作為分隔符。 sed 's/\([^:]*\):\([^:]*\):\(.*\).*/\3,\2,\1/g' file_tmp.txt #結果 /root/,/usr/local/bin,/usr/apps/bin /opt/bin,/usr/apps/sbin,/usr/local/sbincat employee.txt # 結果 101,John Doe,CEO 102,Jason Smith,IT Manager 103,Raj Reddy,Sysadmin 104,Anand Ram,Developer 105,Jane Miller,Sales Manager#對不同列進行操作并重新排序 sed 's/\([^,]*\),\([^,]*\),\(.*\).*/\3,\2,\1/g' employee.txt#結果 CEO,John Doe,101 IT Manager,Jason Smith,102 Sysadmin,Raj Reddy,103 Developer,Anand Ram,104 Sales Manager,Jane Miller,105替換結合正則表達式
行結尾替換
# 替換每行結尾前2個字符為” new Append”(不含換行)。 sed 's/..$/,new Append/' emp.txt#結果 7369,smith,clerk,7902,'1980-12-17',800,null,new Append 7499,allen,salesman,7698,'1981-2-20',1600,300,new Append 7521,ward,salesman,7698,'1981-2-22',1250,500,new Append#原始數據 7369,smith,clerk,7902,'1980-12-17',800,null,20 7499,allen,salesman,7698,'1981-2-20',1600,300,30 7521,ward,salesman,7698,'1981-2-22',1250,500,30截斷關鍵字之后的內容
#將salesman后的內容替換為空,即“刪除”。這里它前面的一個字符也替換為空 # sed 's/.salesman.*//' emp.txt # 結果 7369,smith,clerk,7902,'1980-12-17',800,null,20 7499,allen 7521,ward# 原始文件(部分) 7369,smith,clerk,7902,'1980-12-17',800,null,20 7499,allen,salesman,7698,'1981-2-20',1600,300,30 7521,ward,salesman,7698,'1981-2-22',1250,500,30刪除以某個關鍵字開頭的行
#刪除以”--”開頭的行,--.*即匹配以—開頭的所有行。 # 這里又用到多命令執行以”;”拼接,其中^$指的是空行。 sed -e 's/--.*//; /^$/ d' emp.txt刪除以某個關鍵字結尾的行
#刪除以”--”結尾的行,.*--$即匹配以—結尾的所有行。 # 這里又用到多命令執行以”;”拼接,其中^$指的是空行。 sed -e 's/.*--$//; /^$/ d' emp.txtDos文件格式轉Unix文件格式
#眾所周知,Windows(DOS)的行分隔符是回車(CR)換行(LF),而Unix(Linux)的則是(換行)LF。所以如果想轉換即將每行的倒數第一個(不含LF)的CR替換為空即可。 sed 's/.$//' emp.txtGNU版文本替換延展
局部小寫關鍵字行替換
# 1 將scoot關鍵字替換為SCoTt,這里o和t前分別加了\l標識,可認為做了轉義,即不做大寫處理。 sed -n 's/scott/SC\lOT\lT/p' emp.txt#以下內容僅摘錄更改部分的數據,完整的數據未附錄。 7788,SCoTt,analyst,7566,'1982-12-9,3000,null,20,scott# 原始文本內容 7788,scott,analyst,7566,'1982-12-9,3000,null,20,scott全局小寫關鍵字行替換
# 2 將scoot關鍵字替換為Scott,這里盡管替換時寫的是”OTT”但是前面加了\L標識,所以全部都變成了小寫的ott。 sed -n 's/scott/SC\LOTT/p' emp.txt# 執行結果,ott全是小寫,盡管替換是是“OTT” 7788,SCott,analyst,7566,'1982-12-9,3000,null,20,scott注:1 \L和\l(即大寫L和小寫l的區別在于l只能控制后面的1個字符為小寫,而L則是后面所有的字符都是小寫)。2 不論\l還是\L都只是對匹配到的第一個關鍵字起作用,第二和之后的不起作用。3 針對問題2,想對所有匹配的關鍵字起作用,想要加g選項(標識)。局部控制大寫關鍵字行替換
# 3 將scoot關鍵字替換為SCoTt,這里o和t前分別加了\l標識,可認為做了轉義,即不做大寫處理。 sed -n 's/scott/sc\uot\ut/p' emp.txt#以下內容僅摘錄更改部分的數據,完整的數據未附錄。 7788,scOtT,analyst,7566,'1982-12-9,3000,null,20,scott# 原始文本內容 7788,scott,analyst,7566,'1982-12-9,3000,null,20,scott全局大寫關鍵字行替換
# 4 將scoot關鍵字替換為Scott,這里盡管替換時寫的是”OTT”但是前面加了\L標識,所以全部都變成了小寫的ott。sed -n 's/scott/sc\Uott/p' emp.txt # 執行結果,OTT全是大寫,盡管替換是小寫“ott” 7788,scOTT,analyst,7566,'1982-12-9,3000,null,20,scott注:1 特點和上節類似,這里\l、\u和 \U、\L可以一同記憶,即盡管在sed里輸入的是大小寫,但經過這些轉換標識后會做相應的小大寫轉換。2 這里l即low,u即是UPPER。局部保留關鍵字行替換
# 5 使用\U或者\L時如果想后面有些部分保留小寫或者大寫時可用\E標識。 # 示例 將scott替換為scOTT king sed -n 's/scott/sc\Uott \Eking/p' emp.txt如果不加\E,則結果會全部替換為 #sed -n 's/scott/sc\Uott king/p' emp.txt 7788,scOTT KING,analyst,7566,'1982-12-9,3000,null,20,scott總結
以上是生活随笔為你收集整理的打开高效文本编辑之门_熟悉Linux Sed的替换命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业年金如何扣税 大家应该了解的一些信息
- 下一篇: 打开高效文本编辑之门_Linux Sed