sed 簡明教程

sed 簡明教程

轉自:https://coolshell.cn/articles/9104.html

awk于1977年出生,今年36歲本命年,sed比awk大2-3歲,awk就像林妹妹,sed就是寶玉哥哥了。所以 林妹妹跳了個Topless,他的哥哥sed坐不住了,也一定要出來抖一抖。

sed全名叫stream editor,流編輯器,用程序的方式來編輯文本,相當的hacker啊。sed基本上就是玩正則模式匹配,所以,玩sed的人,正則表達式一般都比較強。

同樣,本篇文章不會說sed的全部東西,你可以參看sed的手冊,我這里主要還是想和大家競爭一下那些從手機指縫間或馬桶里流走的時間,用這些時間來學習一些東西。當然,接下來的還是要靠大家自己雙手。

用s命令替換

我使用下面的這段文本做演示:

$ cat pets.txt
This is my catmy cat's name is betty
This is my dogmy dog's name is frank
This is my fishmy fish's name is george
This is my goatmy goat's name is adam

把其中的my字符串替換成Hao Chen’s,下面的語句應該很好理解(s表示替換命令,/my/表示匹配my,/Hao Chen’s/表示把匹配替換成Hao Chen’s,/g 表示一行上的替換所有的匹配):

$ sed "s/my/Hao Chen's/g" pets.txt
This is Hao Chen's catHao Chen's cat's name is betty
This is Hao Chen's dogHao Chen's dog's name is frank
This is Hao Chen's fishHao Chen's fish's name is george
This is Hao Chen's goatHao Chen's goat's name is adam

注意:如果你要使用單引號,那么你沒辦法通過 \’ 這樣來轉義,就有雙引號就可以了,在雙引號內可以用 \” 來轉義。

再注意:上面的sed并沒有對文件的內容改變,只是把處理過后的內容輸出,如果你要寫回文件,你可以使用重定向,如:

$ sed "s/my/Hao Chen's/g" pets.txt > hao_pets.txt

或使用 -i 參數直接修改文件內容:

$ sed -i "s/my/Hao Chen's/g" pets.txt

在每一行最前面加點東西:

$ sed 's/^/#/g' pets.txt
#This is my cat
#  my cat's name is betty
#This is my dog
#  my dog's name is frank
#This is my fish
#  my fish's name is george
#This is my goat
#  my goat's name is adam

在每一行最后面加點東西:

$ sed 's/$/ --- /g' pets.txt
This is my cat ---my cat's name is betty ---
This is my dog ---my dog's name is frank ---
This is my fish ---my fish's name is george ---
This is my goat ---my goat's name is adam ---

順手介紹一下正則表達式的一些最基本的東西:

  • ^ 表示一行的開頭。如:/^#/ 以#開頭的匹配。
  • $ 表示一行的結尾。如:/}$/ 以}結尾的匹配。
  • \< 表示詞首。 如:\<abc 表示以 abc 為首的詞。
  • \> 表示詞尾。 如:abc\> 表示以 abc 結尾的詞。
  • . 表示任何單個字符。
  • * 表示某個字符出現了0次或多次。
  • [ ] 字符集合。 如:[abc] 表示匹配a或b或c,還有 [a-zA-Z] 表示匹配所有的26個字符。如果其中有^表示反,如 [^a] 表示非a的字符

正規則表達式是一些很牛的事,比如我們要去掉某html中的tags:

<b>This</b> is what <span style="text-decoration: underline;">I</span> meant. Understand?

看看我們的sed命令

# 如果你這樣搞的話,就會有問題
$ sed 's/<.*>//g' html.txtUnderstand?# 要解決上面的那個問題,就得像下面這樣。
# 其中的'[^>]' 指定了除了>的字符重復0次或多次。
$ sed 's/<[^>]*>//g' html.txt
This is what I meant. Understand?

我們再來看看指定需要替換的內容:

$ sed "3s/my/your/g" pets.txt
This is my catmy cat's name is betty
This is your dogmy dog's name is frank
This is my fishmy fish's name is george
This is my goatmy goat's name is adam

下面的命令只替換第3到第6行的文本。

$ sed "3,6s/my/your/g" pets.txt
This is my catmy cat's name is betty
This is your dogyour dog's name is frank
This is your fishyour fish's name is george
This is my goatmy goat's name is adam
$ cat my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam

只替換每一行的第一個s:

$ sed 's/s/S/1' my.txt
ThiS is my cat, my cat's name is betty
ThiS is my dog, my dog's name is frank
ThiS is my fish, my fish's name is george
ThiS is my goat, my goat's name is adam

只替換每一行的第二個s:

$ sed 's/s/S/2' my.txt
This iS my cat, my cat's name is betty
This iS my dog, my dog's name is frank
This iS my fish, my fish's name is george
This iS my goat, my goat's name is adam

只替換第一行的第3個以后的s:

$ sed 's/s/S/3g' my.txt
This is my cat, my cat'S name iS betty
This is my dog, my dog'S name iS frank
This is my fiSh, my fiSh'S name iS george
This is my goat, my goat'S name iS adam

多個匹配

如果我們需要一次替換多個模式,可參看下面的示例:(第一個模式把第一行到第三行的my替換成your,第二個則把第3行以后的This替換成了That)

$ sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
This is your cat, your cat's name is betty
This is your dog, your dog's name is frank
That is your fish, your fish's name is george
That is my goat, my goat's name is adam

上面的命令等價于:(注:下面使用的是sed的-e命令行參數)

sed -e '1,3s/my/your/g' -e '3,**$s**/This/That/g' my.txt

我們可以使用&來當做被匹配的變量,然后可以在基本左右加點東西。如下所示:

$ sed 's/my/[&]/g' my.txt
This is [my] cat, [my] cat's name is betty
This is [my] dog, [my] dog's name is frank
This is [my] fish, [my] fish's name is george
This is [my] goat, [my] goat's name is adam

圓括號匹配

使用圓括號匹配的示例:(圓括號括起來的正則表達式所匹配的字符串會可以當成變量來使用,sed中使用的是\1,\2…)

$ sed 's/This is my \([^,&]*\),.*is \(.*\)/\1:\2/g' my.txt
cat:betty
dog:frank
fish:george
goat:adam

上面這個例子中的正則表達式有點復雜,解開如下(去掉轉義字符):

正則為:This is my ([^,]*),.*is (.*)
匹配為:This is my (cat),……….is (betty)

然后:\1就是cat,\2就是betty

sed的命令

讓我們回到最一開始的例子pets.txt,讓我們來看幾個命令:

N命令

先來看N命令 —— 把下一行的內容納入當成緩沖區做匹配。

下面的的示例會把原文本中的偶數行納入奇數行匹配,而s只匹配并替換一次,所以,就成了下面的結果:

$ sed 'N;s/my/your/' pets.txt
This is your catmy cat's name is betty
This is your dogmy dog's name is frank
This is your fishmy fish's name is george
This is your goatmy goat's name is adam

也就是說,原來的文件成了:

This is my cat\n  my cat's name is betty
This is my dog\n  my dog's name is frank
This is my fish\n  my fish's name is george
This is my goat\n  my goat's name is adam

這樣一來,下面的例子你就明白了,

$ sed 'N;s/\n/,/' pets.txt
This is my cat,  my cat's name is betty
This is my dog,  my dog's name is frank
This is my fish,  my fish's name is george
This is my goat,  my goat's name is adam
a命令和i命令

a命令就是append, i命令就是insert,它們是用來添加行的。如:

# 其中的1i表明,其要在第1行前插入一行(insert)
$ sed "1 i This is my monkey, my monkey's name is wukong" my.txt
This is my monkey, my monkey's name is wukong
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam# 其中的1a表明,其要在最后一行后追加一行(append)
$ sed "$ a This is my monkey, my monkey's name is wukong" my.txt
This is my cat, my cat's name is betty
This is my monkey, my monkey's name is wukong
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam

我們可以運用匹配來添加文本:

# 注意其中的/fish/a,這意思是匹配到/fish/后就追加一行
$ sed "/fish/a This is my monkey, my monkey's name is wukong" my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my monkey, my monkey's name is wukong
This is my goat, my goat's name is adam

下面這個例子是對每一行都挺插入:

$ sed "/my/a ----" my.txt
This is my cat, my cat's name is betty
----
This is my dog, my dog's name is frank
----
This is my fish, my fish's name is george
----
This is my goat, my goat's name is adam
----
c命令

c 命令是替換匹配行

$ sed "2 c This is my monkey, my monkey's name is wukong" my.txt
This is my cat, my cat's name is betty
This is my monkey, my monkey's name is wukong
This is my fish, my fish's name is george
This is my goat, my goat's name is adam$ sed "/fish/c This is my monkey, my monkey's name is wukong" my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my monkey, my monkey's name is wukong
This is my goat, my goat's name is adam
d命令

刪除匹配行

$ sed '/fish/d' my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my goat, my goat's name is adam$ sed '2d' my.txt
This is my cat, my cat's name is betty
This is my fish, my fish's name is george
This is my goat, my goat's name is adam$ sed '2,$d' my.txt
This is my cat, my cat's name is betty
p命令

打印命令

你可以把這個命令當成grep式的命令

# 匹配fish并輸出,可以看到fish的那一行被打了兩遍,
# 這是因為sed處理時會把處理的信息輸出
$ sed '/fish/p' my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my fish, my fish's name is george
This is my goat, my goat's name is adam# 使用n參數就好了
$ sed -n '/fish/p' my.txt
This is my fish, my fish's name is george# 從一個模式到另一個模式
$ sed -n '/dog/,/fish/p' my.txt
This is my dog, my dog's name is frank
This is my fish, my fish's name is george#從第一行打印到匹配fish成功的那一行
$ sed -n '1,/fish/p' my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george

幾個知識點

好了,下面我們要介紹四個sed的基本知識點:

Pattern Space

第零個是關于-n參數的,大家也許沒看懂,沒關系,我們來看一下sed處理文本的偽代碼,并了解一下Pattern Space的概念:

foreach line in file {//放入把行Pattern_SpacePattern_Space <= line;// 對每個pattern space執行sed命令Pattern_Space <= EXEC(sed_cmd, Pattern_Space);// 如果沒有指定 -n 則輸出處理后的Pattern_Spaceif (sed option hasn't "-n")  {print Pattern_Space}
}
Address

第一個是關于address,幾乎上述所有的命令都是這樣的(注:其中的!表示匹配成功后是否執行命令)

[address[,address]][!]{cmd}

address可以是一個數字,也可以是一個模式,你可以通過逗號要分隔兩個address 表示兩個address的區間,參執行命令cmd,偽代碼如下:

bool bexec = false
foreach line in file {if ( match(address1) ){bexec = true;}if ( bexec == true) {EXEC(sed_cmd);}if ( match (address2) ) {bexec = false;}
}

關于address可以使用相對位置,如:

# 其中的+3表示后面連續3行
$ sed '/dog/,+3s/^/# /g' pets.txt
This is my catmy cat's name is betty
# This is my dog
#   my dog's name is frank
# This is my fish
#   my fish's name is george
This is my goatmy goat's name is adam
命令打包

第二個是cmd可以是多個,它們可以用分號分開,可以用大括號括起來作為嵌套命令。下面是幾個例子:

$ cat pets.txt
This is my catmy cat's name is betty
This is my dogmy dog's name is frank
This is my fishmy fish's name is george
This is my goatmy goat's name is adam# 對3行到第6行,執行命令/This/d
$ sed '3,6 {/This/d}' pets.txt
This is my catmy cat's name is bettymy dog's name is frankmy fish's name is george
This is my goatmy goat's name is adam# 對3行到第6行,匹配/This/成功后,再匹配/fish/,成功后執行d命令
$ sed '3,6 {/This/{/fish/d}}' pets.txt
This is my catmy cat's name is betty
This is my dogmy dog's name is frankmy fish's name is george
This is my goatmy goat's name is adam# 從第一行到最后一行,如果匹配到This,則刪除之;如果前面有空格,則去除空格
$ sed '1,${/This/d;s/^ *//g}' pets.txt
my cat's name is betty
my dog's name is frank
my fish's name is george
my goat's name is adam 
Hold Space

第三個我們再來看一下 Hold Space

接下來,我們需要了解一下Hold Space的概念,我們先來看四個命令:

  • g: 將hold space中的內容拷貝到pattern space中,原來pattern space里的內容清除
  • G: 將hold space中的內容append到pattern space\n后
  • h: 將pattern space中的內容拷貝到hold space中,原來的hold space里的內容被清除
  • H: 將pattern space中的內容append到hold space\n后
  • x: 交換pattern space和hold space的內容

這些命令有什么用?我們來看兩個示例吧,用到的示例文件是:

$ cat t.txt
one
two
three

第一個示例:

$ sed 'H;g' t.txt
oneone
twoone
two
three

是不是有點沒看懂,我作個圖你就看懂了。

在這里插入圖片描述

第二個示例,反序了一個文件的行:

$ sed '1!G;h;$!d' t.txt
three
two
one

其中的 ‘1!G;h;$!d’ 可拆解為三個命令

  • 1!G —— 只有第一行不執行G命令,將hold space中的內容append回到pattern space
  • h —— 第一行都執行h命令,將pattern space中的內容拷貝到hold space中
  • $!d —— 除了最后一行不執行d命令,其它行都執行d命令,刪除當前行

這個執行序列很難理解,做個圖如下大家就明白了

在這里插入圖片描述

就先說這么多吧,希望對大家有用。

(全文完)

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

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

相關文章

awk 簡明教程

awk 簡明教程 轉自&#xff1a;https://coolshell.cn/articles/9070.html 有一些網友看了前兩天的《Linux下應該知道的技巧》希望我能教教他們用awk和sed&#xff0c;所以&#xff0c;出現了這篇文章。我估計這些80后的年輕朋友可能對awk/sed這類上古神器有點陌生了&#xff0c…

應該知道的LINUX技巧

應該知道的LINUX技巧 轉自&#xff1a;https://coolshell.cn/articles/8883.html 這篇文章來源于Quroa的一個問答《What are some time-saving tips that every Linux user should know?》—— Linux用戶有哪些應該知道的提高效率的技巧。我覺得挺好的&#xff0c;總結得比較好…

[深度][PyTorch] DDP系列第一篇:入門教程

[深度][PyTorch] DDP系列第一篇&#xff1a;入門教程 轉自&#xff1a;[原創][深度][PyTorch] DDP系列第一篇&#xff1a;入門教程 概覽 想要讓你的PyTorch神經網絡在多卡環境上跑得又快又好&#xff1f;那你definitely需要這一篇&#xff01; No one knows DDP better than I…

[深度][PyTorch] DDP系列第二篇:實現原理與源代碼解析

[深度][PyTorch] DDP系列第二篇&#xff1a;實現原理與源代碼解析 轉自&#xff1a;https://zhuanlan.zhihu.com/p/187610959 概覽 想要讓你的PyTorch神經網絡在多卡環境上跑得又快又好&#xff1f;那你definitely需要這一篇&#xff01; No one knows DDP better than I do! …

[深度][PyTorch] DDP系列第三篇:實戰與技巧

[深度][PyTorch] DDP系列第三篇&#xff1a;實戰與技巧 轉自&#xff1a;https://zhuanlan.zhihu.com/p/250471767 零. 概覽 想要讓你的PyTorch神經網絡在多卡環境上跑得又快又好&#xff1f;那你definitely需要這一篇&#xff01; No one knows DDP better than I do! – – …

PIL、OpenCV中resize算子實現不同的問題

PIL、OpenCV中resize算子實現不同的問題 測試圖像&#xff1a;https://raw.githubusercontent.com/TropComplique/ssd-pytorch/master/images/dogs-and-cats.jpg &#xff08;直接 wget 可獲得&#xff09; 測試版本&#xff1a; opencv-python 4.4.0.46Pillow 8.0.1 測試代…

mac X11 XQuartz的安裝與使用

mac X11 XQuartz的安裝與使用 本地系統&#xff1a;MacOS 12.4 遠程主機系統&#xff1a;Ubuntu 18.04 命令說明 ssh命令 ssh 命令大家很熟悉了&#xff0c;這里僅介紹與 X11 forwarding 相關的幾個選項。 本部分譯自 ssh 命令手冊&#xff0c;可見 man ssh -X &#xf…

機器學習:系統設計與實現 分布式訓練

機器學習系統:設計與實現 分布式訓練 轉自&#xff1a;https://openmlsys.github.io/chapter_distributed_training/index.html 隨著機器學習的進一步發展&#xff0c;科學家們設計出更大型&#xff0c;更多功能的機器學習模型&#xff08;例如說&#xff0c;GPT-3&#xff09;…

Linux命令行及各常用工具代理設置

Linux命令行及各常用工具代理設置 命令行代理設置 1 通過命令行指定 直接為當前命令行設置代理 對當前終端的全部工具&#xff08;apt、curl、wget、git 等全都有效&#xff09;以下僅以 http 代理為例&#xff0c;如果是其他協議&#xff08;如 socks 等&#xff09;自行改…

VimScript 五分鐘入門(翻譯)

VimScript 五分鐘入門&#xff08;翻譯&#xff09; 轉自&#xff1a;https://zhuanlan.zhihu.com/p/37352209 譯注&#xff1a;折騰 Vim 當然要能看懂和改寫相關腳本&#xff0c;而中文資料匱乏&#xff0c;缺一個提綱挈領的教程。本文翻譯自 Andrew Scala 的 《Five Minute V…

C++多線程推理、生產者消費者模式封裝

C多線程推理、生產者消費者模式封裝 tensorRT從零起步邁向高性能工業級部署&#xff08;就業導向&#xff09; 課程筆記&#xff0c;講師講的不錯&#xff0c;可以去看原視頻支持下。 深度學習推理中的多線程知識概覽 本章介紹的多線程主要是指算法部署時所涉及的多線程內容&a…

在Python中調用C/C++:cython及pybind11

在Python中調用C/C&#xff1a;cython及pybind11 轉自&#xff1a;https://zhuanlan.zhihu.com/p/442935082 Python寫起來非常方便, 但面對大量for循環的時候, 執行速度有些捉急. 原因在于, python是一種動態類型語言, 在運行期間才去做數據類型檢查, 這樣效率就很低(尤其是大規…

Pytorch導出onnx模型,C++轉化為TensorRT并實現推理過程

Pytorch導出onnx模型&#xff0c;C轉化為TensorRT并實現推理過程 前言 本文為旨在實現整個Python導出PyTorch模型&#xff0c;C轉化為TensorRT并實現推理過程過程&#xff0c;只與模型推理&#xff0c;模型部署相關&#xff0c;不涉及模型訓練。為突出整個部署過程而非具體模…

從零Makefile落地算法大項目,完整案例教程

從零Makefile落地算法大項目&#xff0c;完整案例教程 轉自&#xff1a;從零Makefile落地算法大項目&#xff0c;完整案例教程 作者&#xff1a;手寫AI 前言 在這里&#xff0c;你能學到基于Makefile的正式大項目的使用方式和考慮&#xff0c;相信我&#xff0c;其實可以很簡單…

PyTorch擴展自定義PyThonC++(CUDA)算子的若干方法總結

PyTorch擴展自定義PyThon/C(CUDA)算子的若干方法總結 轉自&#xff1a;https://zhuanlan.zhihu.com/p/158643792 作者&#xff1a;奔騰的黑貓 在做畢設的時候需要實現一個PyTorch原生代碼中沒有的并行算子&#xff0c;所以用到了這部分的知識&#xff0c;再不總結就要忘光了 &a…

給 Python 算法插上性能的翅膀——pybind11 落地實踐

給 Python 算法插上性能的翅膀——pybind11 落地實踐 轉自&#xff1a;https://zhuanlan.zhihu.com/p/444805518 作者&#xff1a;jesonxiang&#xff08;向乾彪&#xff09;&#xff0c;騰訊 TEG 后臺開發工程師 1. 背景 目前 AI 算法開發特別是訓練基本都以 Python 為主&…

chrome自動提交文件_收集文檔及提交名單統計

知乎文章若有排版問題請見諒&#xff0c;原文放在個人博客中【歡迎互踩&#xff01;】文叔叔文檔收集使用動機在我們的學習工作中&#xff0c;少不了要讓大家集體提交文件的情況&#xff0c;舉個最簡單的例子&#xff1a;收作業。 傳統的文件收集流程大致是&#xff1a;群內發出…

Pytorch自定義C++/CUDA擴展

Pytorch自定義C/CUDA擴展 翻譯自&#xff1a;官方文檔 PyTorch 提供了大量與神經網絡、張量代數、數據整理和其他操作。但是&#xff0c;我們有時會需要更加定制化的操作。例如&#xff0c;想要使用論文中找到的一種新型的激活函數&#xff0c;或者實現自己設計的算子。 在 Py…

惠普800g1支持什么內存_惠普黑白激光打印機哪種好 惠普黑白激光打印機推薦【圖文詳解】...

打印機的出現讓我們在生活和日常工作中變得越來越方便&#xff0c;不過隨著科技的發展&#xff0c;打印機的類型也變得非常多&#xff0c;其中就有黑白激光打印機&#xff0c;而黑白激光打印機的品牌也有很多&#xff0c;比如我們的惠普黑白激光打印機&#xff0c;今天小編就給…

控制臺輸出顏色控制

控制臺輸出顏色控制 轉自&#xff1a;https://cloud.tencent.com/developer/article/1142372 前端時間&#xff0c;寫了一篇 PHP 在 Console 模式下的進度顯示 &#xff0c;正好最近的一個數據合并項目需要用到控制臺顏色輸出&#xff0c;所以就把相關的信息整理下&#xff0c;…