Linux 三劍客之sed

HammerZe發表於2021-12-21

Linux 三劍客之sed

image


命令補充:

sort命令

對文字檔案的內容,以行為單位來排序,比較原則是從一行的首個字元依次向後,按照字元對應的ASCII碼值進行比較,預設升序

  • 格式:sort [引數] [-o 輸出檔案]

  • 引數:

    • -b: 不包括開頭的空白字元,從第一個可見字元比較
    • -n:按照數值的大小排序
    • -r:以相反的順序來排序
    • -k:以某列進行排序
    • -t<分隔字元> : 指定排序時所用的欄位分隔字元
    • -o<輸出檔案> : 將排序後的結果存入指定的檔案
    • -k: 選擇以哪個列進行排序
    • -f: 排序時,忽略大小寫字母
    • -u:排序過程中去除重複的行
  • 例項如下:

# 常用引數演示,檔案內容自己編寫

# 排序
[root@localhost ~]# cat 1.sh 
aa
ab
ac
ad
[root@localhost ~]# sort 1.sh 
aa
ab
ac
ad

# -n按照數值大小排序
[root@localhost ~]# sort -n 1.sh 
1aa
22ab
32ac
42ad

# -r 以相反的順序來排序,降序輸出
[root@localhost ~]# sort -r 1.sh 
aaa
4ad
32ac
22ab
1aa
1

# 按第一列排序
[root@localhost ~]# sort -k1 1.sh  
1
1aa
22ab
32ac
4ad
aaa

# -t:指定分割符,預設是以空格為分隔符
# 注:分隔符排序前有空格行
[root@localhost ~]# cat 3.sh
|1|2|3|5|6|2|1|3|7|8
|3|4|4|5|4|6|7|8|9|8
|2|3|4|5|4|6|5|7
|3|4|6|8|9|0|7|0|7
|3|2|4|2|4|2|4|2|3|4
[root@localhost ~]# sort -n -r -k2 -t '|' 3.sh 
|3|4|6|8|9|0|7|0|7
|3|4|4|5|4|6|7|8|9|8
|3|2|4|2|4|2|4|2|3|4
|2|3|4|5|4|6|5|7
|1|2|3|5|6|2|1|3|7|8

# `-u`:排序過程中去除重複的行
[root@localhost ~]# cat 4.sh
aaaaaa
aaaaaa
bbbbbb
bbbbbb
cccccc
cccccc
[root@localhost ~]# sort -u 4.sh 
aaaaaa
bbbbbb
cccccc

# -o<輸出檔案> :  將排序後的結果存入指定的檔案
[root@localhost ~]# sort -u 4.sh > 5.sh
[root@localhost ~]# cat 5.sh
aaaaaa
bbbbbb
cccccc

uniq命令

用於檢查及刪除文字檔案中重複出現的行列,一般與 sort 命令結合使用

  • 格式:uniq [引數] [檔案]

  • 引數:

    • -c: 在輸出行前面加上每行在輸入檔案中出現的次數
    • -d:僅顯示重複出現的行列
    • -u:僅顯示不重複行列
  • 例項如下:

# 去重
[root@localhost ~]# cat 4.sh 
aaaaaa
aaaaaa
bbbbbb
bbbbbb
cccccc
cccccc
[root@localhost ~]# uniq 4.sh 
aaaaaa
bbbbbb
cccccc

# 注意,去重是相鄰重複內容去重,所以先排序再去重
[root@localhost ~]# cat 5.sh 
123
124
123
123
123
124
124
124
125
126
[root@localhost ~]# uniq 5.sh 
123
124
123
124
125
126
# 這樣的話就沒有達到去重的效果,需要搭配sort使用
[root@localhost ~]# sort -n 5.sh|uniq 
123
124
125
126

# -c: 在輸出行前面加上每行在輸入檔案中出現的次數
[root@localhost ~]# sort -n 5.sh|uniq -c
      4 123
      4 124
      1 125
      1 126
      
# -u:僅顯示不重複行列
[root@localhost ~]# sort -n 5.sh|uniq -u
125
126

cut命令

cut命令用來輸出每一行中的指定部分,刪除(剪下)檔案中指定位元組,欄位

  • 格式:cut [-b/c/f] [file]

  • 定位方法:

    • -b:位元組
    • -c:字元
    • -f:域

    注.必須指定-b,-c,-f其中一種

  • 引數:

    • -b:以位元組為單位進行分割。這些位元組位置將忽略多位元組字元邊界,除非也指定了 -n 標誌
    • -c:以字元為單位進行分割
    • -d:自定義分隔符,預設為製表符(Tab)
    • -f :與-d一起使用,指定顯示哪個區域
    • -n:取消分割多位元組字元。僅和 -b 標誌一起使用。如果字元的最後一個位元組落在由 -b 標誌的 List 引數指示的<br />範圍之內,該字元將被寫出;否則,該字元將被排除。
  • 例項如下:

    -b位元組(英文數字)模式如下

    # 用當前登入使用者資訊舉例
    [root@localhost ~]# who
    root     tty1         2021-12-21 18:47
    root     pts/0        2021-12-21 16:52 (192.168.15.1)
    
    # -b 模式提取位元組
    [root@localhost ~]# who | cut -b 3
    o
    o
    # 提取第1,2,3列的位元組
    [root@localhost ~]# who | cut -b 1,2,3
    roo
    roo
    [root@localhost ~]# who | cut -b 1-3
    roo
    roo
    # cut命令如果使用了-b選項,那麼執行此命令時,cut會先把-b後面所有的定位進行從小到大排序,然後再提取。不能顛倒定位的順序。
    [root@localhost ~]# who | cut -b -3,3-
    root     tty1         2021-12-21 18:47
    root     pts/0        2021-12-21 16:52 (192.168.15.1)
    # -3表示從第一個位元組到第三個位元組,3-表示從第三個位元組到行尾
    # 執行上述語句,第三個位元組不會重疊輸出
    

    -c模式字元(漢字可用)如下:

    [root@localhost ~]# cat a.txt 
    路飛
    山治
    索隆
    娜美
    黑鬍子
    白鬍子
    # 如果用b模式就會不完全輸出
    [root@localhost ~]# cut -b 2 a.txt 
    ·
    ±
    ´
    ¨
    »
    # 用c模式,區別就看出來了
    [root@localhost ~]# cut -c 2 a.txt 
    飛
    治
    隆
    美
    胡
    胡
    # -c則會以字元為單位,輸出正常;而-b只會傻傻的以位元組(8位二進位制位)來計算,輸出就是亂碼。
    
    # 使用-n搭配b模式使用,解決亂碼
    [root@localhost ~]# cut -nb 2 a.txt 
    飛
    治
    隆
    美
    胡
    胡
    

    -f模式,-b和-c只能在固定格式的文件中提取資訊,而對於非固定格式的資訊則束手無策,這時候使用-f模式,在使用的時候注意設定間隔符

    # 提取使用者名稱
    [root@localhost ~]# head -n 5 /etc/passwd 
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    [root@localhost ~]# head -n 5 /etc/passwd | cut -d : -f 1
    root
    bin
    daemon
    adm
    lp
    

tr命令

用一個字元來替換另一個字元,或者可以完全刪除一些字元,替換等

  • 格式: tr [OPTION]... SET1 [SET2]

  • 引數:

    • -c :用字串1中字符集的補集替換此字符集,要求字符集為ASCII。
    • -d:刪除指令字元
    • -s:縮減連續重複的字元成指定的單個字元
    • -t:削減 SET1 指定範圍,使之與 SET2 設定長度相等
  • 例項如下:

    # 替換
    [root@localhost ~]# cat 2.sh 
    +a+b+c+d
    +e+f+g
    +h+i+j+k
    +1+2+a+s+d+a+s
    +a+b+c+1+2+3
    # 將2.sh中的'+'替換成'|'
    [root@localhost ~]# cat 2.sh | tr + '|'
    |a|b|c|d
    |e|f|g
    |h|i|j|k
    |1|2|a|s|d|a|s
    |a|b|c|1|2|3
    # 將2.sh小寫字母替換成大寫字母
    [root@localhost ~]# cat 2.sh  | tr a-z A-Z
    |A|B|C|D
    |E|F|G
    |H|I|J|K
    |1|2|A|S|D|A|S
    |A|B|C|1|2|3
    
    # 刪除
    # -d 刪除2.sh中的ab字母
    [root@localhost ~]# cat 2.sh  | tr -d "ab" > new_file
    [root@localhost ~]# cat new_file 
    |||c|d
    |e|fffff|g
    |h|i|j|k
    |1|2||s|d||s
    |||c|1|2|3
    
    
    # -s 刪除連續的字元,相當於去重,只保留第一個
    [root@localhost ~]# cat 2.sh 
    |aaaaaaaaa|bbbbbbb|c|d
    |e|fffff|bbbbbg
    |h|i|j|k
    |1|2|a|s|d|a|s
    |a|b|c|1|2|3
    [root@localhost ~]# cat 2.sh  | tr -s [a-z] > new_file
    [root@localhost ~]# cat new_file 
    |a|b|c|d
    |e|f|bg
    |h|i|j|k
    |1|2|a|s|d|a|s
    |a|b|c|1|2|3
    # -s還有替換的功能,將2.sh中的'|',替換成'-'
    [root@localhost ~]# cat 2.sh  | tr -s "|" "-"
    -aaaaaaaaa-bbbbbbb-c-d
    -e-fffff-bbbbbg
    -h-i-j-k
    -1-2-a-s-d-a-s
    -a-b-c-1-2-3
    

wc命令

wc指令可以計算檔案的位元組數,詞數,或者列數,若不指定檔名稱、或是所給予的檔名為"-",則wc指令會從標準輸入裝置讀取資料。

注:在Linux系統中,一段連續的數字或字母組合為一個詞

在預設的情況下,wc將計算指定檔案的行數、字數,以及位元組數

  • 格式:wc [OPTION]... [FILE]...

  • 引數:

    • -c:統計檔案的位元組(Bytes)數
    • -l:統計檔案的行數
    • -w:統計檔案中的單詞個數,預設以空白字元作為分隔符
  • 例項如下:

    # 統計bytes
    # 檢視2.sh內容
    [root@localhost ~]# cat 2.sh 
    |aaaaaaaaa|bbbbbbb|c|d
    |e|fffff|bbbbbg
    |h|i|j|k
    |1|2|a|s|d|a|s
    |a|b|c|1|2|3
    # 單檔案
    [root@localhost ~]# wc 2.sh
     5  5 76 2.sh   # 對應數字:行數,單詞數,位元組數
     [root@localhost ~]# wc -c 2.sh 
    76 2.sh          # bytes數
    [root@localhost ~]# wc -w 2.sh 
    5 2.sh			# 單詞數
    [root@localhost ~]# wc -l 2.sh 
    5 2.sh			# 行數
    
    # 多檔案
    # 不加引數預設都輸出
    [root@localhost ~]# wc 2.sh 3.sh 4.sh 
      5   5  76 2.sh # 第一個5代表行數未5,單詞數5,位元組數76
      5   5  99 3.sh
      6   6  42 4.sh
     16  16 217 total
     
     [root@localhost ~]# cat 2.sh 3.sh 4.sh | wc
         16      16     217
     # 這樣相當於將三個檔案的行數,單詞書,位元組數求和輸出
     # 加引數
     [root@localhost ~]# wc -c  2.sh 3.sh 4.sh 
     76 2.sh    # 檔案位元組總和
     99 3.sh
     42 4.sh
    217 total
    [root@localhost ~]# wc -l  2.sh 3.sh 4.sh 
      5 2.sh    # 檔案行數總和
      5 3.sh
      6 4.sh
     16 total
     [root@localhost ~]# wc -w  2.sh 3.sh 4.sh 
      5 2.sh    # 檔案單詞數總和
      5 3.sh
      6 4.sh
     16 total
     # 上面的例子是多檔案統計
    

三劍客 - sed

sed,三大劍客之一,sed是一款流媒體編輯器,用來對文字進行過濾,修改操作等

注:grep用來過濾文字,sed用來修改文字,awk用來處理文字

  • 格式:sed [引數] '處理規則' [操作物件]

  • 引數

    • -e:允許多個指令碼被執行,多項編輯

    • -n:取消預設輸出,就是靜默輸出

    • -i:就地編輯,直接修改原始檔(慎用)

    • -r:使用擴充正規表示式(和egrep一樣)

    • -f:指定sed匹配規則指令碼檔案

編輯模式:

  • d:刪除模式
  • p:列印(P列印第一行)
  • a:在當前行後新增一行或多行
  • i:在當前行上一行插入文字(直接修改,原文內容 也會更改)
  • r:從檔案中讀取
  • w:將指定行寫入檔案
  • y:將字元轉換成另一個字元
  • s:替換指定的字元(每一行只替換一次)
  • g:獲得記憶體緩衝區的內容,並替代當前,相當於全部執行
  • i:忽略大小寫(和s模式一起使用的時候,不是單獨使用)
  • &:已經匹配字串標記
  • 定位:(使用兩個斜線)

定位分類:

  • 數字定位:sed ‘行號+模式’ file -- 指定行定位

    • sed '/^g/d' 2.sh
      
  • 正則定位:sed ‘正則+模式’ file -- 正則指定開頭內容

    • sed '3,/^g/d' 2.sh
      
  • 數字和正則定位:sed ‘數字,正則+模式’ file -- 指定行,和開頭

  •    sed '3,/^g/d' 2.sh
    
  • 正則和正則定位:sed ‘正則,正則+模式’ file -- 指定以g和k開頭

  •    sed '/^g/,/^j/d' 2.sh
    
    
  • 處理規則可以使用正則,也可以使用-f指定檔案

  • ?[正則個人總結](python 正規表示式 - HammerZe - 部落格園 (cnblogs.com))

例項如下:

d模式——刪除模式

# 刪除
[root@localhost ~]# cat 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
# 刪除第二行
[root@localhost ~]# sed '2d' 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
# 刪除第一行和第二行
[root@localhost ~]# sed '1,2d' 2.sh 
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3

# -e引數,多個指令碼同時操作,刪除1到2行,和五行
[root@localhost ~]# sed -e '1,2d'  -e '5d' 2.sh 
|h|i|j|k
|1|2|a|s|d|a|s

# -n引數,靜默
[root@localhost ~]# sed -n -e '1,2d'  -e '5d' 2.sh 
[root@localhost ~]# echo $?
0   # 0代表成功,非0代表相反

# -f引數,搭配檔案使用
# 在r.sh 中編寫正則:/b/d  --刪除帶有b的行
[root@localhost ~]# sed -r '/b/d' 2.sh 
|h|i|j|k
|1|2|a|s|d|a|s
[root@localhost ~]# sed -f r.txt 2.sh 
|h|i|j|k
|1|2|a|s|d|a|s
# 這樣兩種結果是一樣的

p模式——列印

# 檢視2.sh
[root@localhost ~]# cat 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
# 列印第一行
[root@localhost ~]# sed "1p" 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3

# -n,靜默輸出
[root@localhost ~]# sed -n "1p" 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
# 這樣就只列印p模式指定的那行

# -e ,多項操作
[root@localhost ~]# cat 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
# 刪除第一行,列印第五行
[root@localhost ~]# sed -e "1d" -e "5p" 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3

# -i,直接修改原始檔,就地編輯
# 修改前
[root@localhost ~]# cat 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
# 修改
[root@localhost ~]# sed -i "7p" 2.sh 
# 修改後增加了一行
[root@localhost ~]# cat 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3

a模式,在當前行後新增一行或多行

# 在第一行下新增xxxx
[root@localhost ~]# sed '1axxxxxxx' 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
xxxxxxx
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3

i模式,在指定行前一行插入

[root@localhost ~]# sed '7i馬叉蟲' 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
馬叉蟲
|a|b|c|1|2|3
|a|b|c|1|2|3

c模式,替換當前行

[root@localhost ~]# cat 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3
# 替換第一行
[root@localhost ~]# sed '1cxxxxxxx' 2.sh 
xxxxxxx
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3

r模式,在檔案中讀內容

 [root@localhost ~]# cat 3.sh 
|1|2|3|5|6|2|1|3|7|8
|3|4|4|5|4|6|7|8|9|8
|2|3|4|5|4|6|5|7
|3|4|6|8|9|0|7|0|7
|3|2|4|2|4|2|4|2|3|4

# 在3.sh中讀取2.sh
[root@localhost ~]# sed '5r 2.sh' 3.sh 
|1|2|3|5|6|2|1|3|7|8
|3|4|4|5|4|6|7|8|9|8
|2|3|4|5|4|6|5|7
|3|4|6|8|9|0|7|0|7
|3|2|4|2|4|2|4|2|3|4
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3

w模式,將指定行寫入檔案

# 把第一行到第七行寫入到input檔案中
[root@localhost ~]# sed '1,7w input.txt' 2.sh 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3
[root@localhost ~]# cat input.txt 
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|aaaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3

y模式,將字元替換成另外一個

# 將第一行到第三行的a替換成A,有a就替換
[root@localhost ~]# sed '1,3y/a/A/' 2.sh 
|AAAAAAAAA|bbbbbbb|c|d
|AAAAAAAAA|bbbbbbb|c|d
|AAAAAAAAA|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3

s模式,字串轉換

# 將字串轉換成另一個字串(每一行只替換一次)
[root@localhost ~]# sed 's/a/啊/' 2.sh 
|啊aaaaaaaa|bbbbbbb|c|d
|啊aaaaaaaa|bbbbbbb|c|d
|啊aaaaaaaa|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|啊|s|d|a|s
|啊|b|c|1|2|3
|啊|b|c|1|2|3

g模式,全部執行

# 全部替換
[root@localhost ~]# sed 's/a/啊/g' 2.sh 
|啊啊啊啊啊啊啊啊啊|bbbbbbb|c|d
|啊啊啊啊啊啊啊啊啊|bbbbbbb|c|d
|啊啊啊啊啊啊啊啊啊|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|啊|s|d|啊|s
|啊|b|c|1|2|3
|啊|b|c|1|2|3

i模式,忽略大小寫

# 和s模式一起使用
[root@localhost ~]# cat 2.sh 
|AAAAAAAAA|bbbbbbb|c|d
|AAAAAAAAA|bbbbbbb|c|d
|AAAAAAAAA|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|a|s|d|a|s
|a|b|c|1|2|3
|a|b|c|1|2|3
# 忽略大小寫
[root@localhost ~]# sed 's/a/啊/gi' 2.sh 
|啊啊啊啊啊啊啊啊啊|bbbbbbb|c|d
|啊啊啊啊啊啊啊啊啊|bbbbbbb|c|d
|啊啊啊啊啊啊啊啊啊|bbbbbbb|c|d
|e|fffff|bbbbbg
|h|i|j|k
|1|2|啊|s|d|啊|s
|啊|b|c|1|2|3
|啊|b|c|1|2|3


&的使用

將nginx.conf中每一行之前增加註釋
	[root@localhost ~]# sed 's/.*/#&/g' /etc/nginx/nginx.conf

練習:

# 將nginx.conf中的註釋行全部去掉
 sed '/^ *#/d' /etc/nginx/nginx.conf

# 將nginx.conf中每一行之前增加註釋
 sed 's/.*/#&/g' /etc/nginx/nginx.conf

# 一鍵修改本機的ip
# 要求如下:
# 192.168.15.100 ---> 192.168.15.101
# 172.16.1.100   ---> 172.16.1.101
sed -i 's/.100/.101/g' /etc/sysconfig/network-scripts/ifcfg-eth[01]

# 將/etc/passwd中的root修改成ROOT
sed -i 's/root/ROOT/g' /etc/passwd

?[cut命令參考博文]((38條訊息) Linux字元擷取命令-cut_小工匠-CSDN部落格_cut命令)

?[tr命令參考](Linux tr命令 | 菜鳥教程 (runoob.com))


相關文章