iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
Software Development

系統與服務雜談系列 第 15

sed - 7 常見案例

前篇回顧
sed - 簡介 讀取編輯文字檔的好工具
sed - 2 Pattern
sed - 3 Delete command
sed - 4 Write commands
sed - 5 Replace command
sed - 6 Hold Space簡介

今天來練習幾個操作

不同系統的換行符號轉換

準備個Windows的txt, win.txt

aaa
bbb
ccc

複製到Linux系統上, 透過cat, 加上-vE
-v代表會顯示看不到的字元,-E則是斷行符號用$顯示
會看到以下內容, ^M不是字面上打出來的,
這是Windows的換行符號CRLF, 需要透過Ctrl+V 接著按Ctrl+M做輸入

cat -vE win.txt
> aaa^M$
> bbb^M$
> ccc^M$

那很常複製過來的文字檔, 通常需要把換行符號做個轉換
sed剛好能幫忙

# 把^M$給都換掉, CRLF to LF
sed 's/^M$//g' 

也能把Linux的換成Windows的換行符號

sed 's/$/^M/g' # LF to CRLF

ini file的一些操作

準備MySQL的My.ini檔

[client]
; comment ItHome!!!
port = 3306
socket = /tmp/mysql.sock
 
[mysqld]
server-id = 1
port = 3306
basedir = /opt/mysql
# tmpdir  = /tmp
# max_connections = 400

嘗試用sed來刪除全部的註解#

\1是regex的back reference, 1表示回前面找第1個匹配成功的內容

sed -r 's/^# +(.*)/\1/' my.ini
sed -r 's/^#[[:space:]]+(.*)/\1/' my.ini
> [client]
> port = 3306
> socket = /tmp/mysql.sock
 
> [mysqld]
> server-id = 1
> port = 3306
> basedir = /opt/mysql
> tmpdir  = /tmp
# max_connections = 400

用sed刪除特定的註解

# [[:space:]]是POSIX class用來代表空格; POSIX在Unix, Linux, Windows大部分都有支援
sed -r 's/^#[[:space:]]+(tmpdir(.*))/\1/' my.ini
> [client]
> port = 3306
> socket = /tmp/mysql.sock
 
> [mysqld]
> server-id = 1
> port = 3306
> basedir = /opt/mysql
> tmpdir  = /tmp
# max_connections = 400

修改特定sesction下的某個key的值

這裡修改client section下的port, 改成3307

sed -ie '/^\[client\]$/,/^\[.*\]/s/port[\[ \t]*= \(.\)*/port = 3307/' my.ini 
# [:space:]是POSIX class用來代表空格 ; [:blank:]代表tab
sed -ie '/^\[client\]$/,/^\[.*\]/s/port[\[[:space:][:blank:]]*= \(.\)*/port = 3307/' my.ini 
cat my.ini
> [client]
> ; comment ItHome!!!
> port = 3307
> socket = /tmp/mysql.sock
 
> [mysqld]
> server-id = 1
> port = 3306
> basedir = /opt/mysql
> # tmpdir  = /tmp
> # max_connections = 400

sed command q (exit sed code)

還有個不太常用的sed command沒說q, 就是執行到這command時, sed就立刻結束.

Question

我準備了個檔案, 有五百萬行文字
先用seq這命令來產生檔案

seq 1 5000000 > hugefile 

今天我分別執行下列操作, 哪個快?

sed 100q filename
sed -n 1,100p filename

Ans :
能透過time這命令來實驗
能發現有執行q離開動作的操作快非常多, 因為就強制結束了;
而另一個操作則乖乖的把五百萬行跑玩, 只是後面的都沒執行print command

time sed 100q hugefile
> real	0m0.001s

time sed -n 1,100p hugefile
> real	0m0.167s

本日小結

sed真的蠻吃Regex熟練度,
設定檔也蠻多用JSON格式做的, 但就沒那麼建議用sed, 太累XD
推薦一個套件jq

----參考來源
鳥哥Linux私房菜 cat
Regex Back Reference
Wiki POSIX Class
time
seq


上一篇
sed - 6 Hold Space簡介
下一篇
xargs - Linux裡好用的工具
系列文
系統與服務雜談32

1 則留言

1
json_liang
iT邦新手 4 級 ‧ 2021-09-30 00:42:48

大推jq 以前有在 gitlab pipeline 用到解析 aws 指令的回應

我要留言

立即登入留言