iT邦幫忙

2021 iThome 鐵人賽

DAY 10
1
Software Development

系統與服務雜談系列 第 10

sed - 2 Pattern

前篇回顧
sed - 簡介 讀取編輯文字檔的好工具

Pattern

這次聊點pattern的更多用法
最常用的用法是/pattern/command, 匹配到的該行做操作.

# 針對行的內容有root的做匹配
sed -n '/root/p' /etc/passwd

但sed有個特別的功能行定位, 就是能快速地跳到某一行開始做匹配操作,也能指定到哪行結束.
用法很簡單, 透過一些簡單範例, 把pattern基本所有組合都列出來.
這次為了方便看出行號, 使用nl(number lines of files) , 幫忙在每一行前面加上行數

  • 只輸出某一行
# 只對第10行做輸出
nl /etc/passwd | sed -n '10p' 
>     10	news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
  • 指定輸出的開始行號到結束行號
# 從第10行開始, 到第20行, 做輸出
nl /etc/passwd | sed -n '10,20p'
> 10	news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
# ...中間忽略
>    20	systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin

# 從第10行開始, 到最後一行, 做輸出
# $表示文件最末行
nl /etc/passwd | sed -n '10,$p'
>    10	news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
# ...中間忽略
>    46	systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
  • 指定輸出的開始行號, 和往後的要執行命令的行數;
    沒法往前, 所有沒有-5這樣的操作
# 從第10行開始, 再往後5行, 到第16行結束並輸出
sed -n '10,+5p' /etc/passwd
  • 從匹配到pattern1的行開始, 到匹配到pattern2的行做結束
    pattern需要用//包起來, 2個pattern間用,做區隔
# 從匹配到news的行開始, 直到匹配到www的行做結束
nl /etc/passwd | sed -n '/news/,/www/p'
>    10	news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
>    11	uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
>    12	proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
>    13	www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
  • 上面的加指定行號的用法
# 從第10行開始,直到匹配到www的行做結束
# 一樣是要有逗號做區隔
nl /etc/passwd | sed -n '10,/www/p' 
>    10	news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
>    11	uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
>    12	proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
>    13	www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
# 從匹配到news開始,直到第13行做結束
nl /etc/passwd | sed -n '/news/,13p'
>    10	news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
>    11	uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
>    12	proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
>    13	www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
  • 指定不輸出的行號
# 不輸出第一行, 本來第一行是root
nl /etc/passwd | sed -n '1!p'
>     2	daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
>     3	bin:x:2:2:bin:/bin:/usr/sbin/nologin
  • 指定不輸出的行號區間
# 第2行~第5行不做輸出
nl /etc/passwd | sed -n '2,5!p' 
>     1	root:x:0:0:root:/root:/bin/bash
>     6	games:x:5:60:games:/usr/games:/usr/sbin/nologin
>     7	man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
  • 指定開始行號, 然後每隔幾行做操作
    開始行號~步長command
# 從第1行開始, 每2行做一次匹配輸出
nl /etc/passwd | sed -n '1~2p' 
>     1	root:x:0:0:root:/root:/bin/bash
>     3	bin:x:2:2:bin:/bin:/usr/sbin/nologin
>     5	sync:x:4:65534:sync:/bin:/bin/sync
  • 只輸出最後一行
    $,作為行定位符號, $表示最後一行
nl /etc/passwd | sed -n '$p' 
>         46	systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin

今日小結

其實行號查找就是快速而已, 但實用性質不高
大部分用到都還是字串匹配, 或者直接指定起訖區間.
但sed就是提供不少方便的定位模式做操作.

Quesion

news假設在第5行, 但後面寫結束是第1行, 這時會怎樣輸出?

nl /etc/passwd | sed -n '/news/,1p'
  • 全部都輸出
  • 都不輸出
  • 只輸出第一行
  • 只輸出匹配到new的行

答案是只輸出匹配到new的行
因為當news被匹配到, 本來就會輸出, 但之後的行, 基本上行號都大於第3行, 這條件等於白設定了.


上一篇
sed - 簡介 讀取編輯文字檔的好工具
下一篇
sed - 3 Delete command
系列文
系統與服務雜談32

尚未有邦友留言

立即登入留言