Skip to content

Instantly share code, notes, and snippets.

@weihanglo
Created October 14, 2017 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weihanglo/578c5d0ac54ebb205751db8165a98520 to your computer and use it in GitHub Desktop.
Save weihanglo/578c5d0ac54ebb205751db8165a98520 to your computer and use it in GitHub Desktop.

I/O Redirection 常用指令紀錄

greptrsedawk 是幾個很常見的標準串流 Standard Streams 處理工具,靠著regex的加持,這些工具使用在 I/O redirection 比起寫個python script快多了,唯一的壞處就是options太多,容易遺忘。本文主要紀錄上述工具使用筆記與心得。

(撰於 2016 年年初,致青春)

sed

sedStream EDitor 的縮寫,最常用來處理pipeline。特色是一次只讀取一行input到buffer處理,導向至「標準輸出(STDOUT)」後,再處理下一行。

使用時機:

取代/刪除/插入 搜尋到之匹配字串

Usage:

#
sed [options] script [inputfile]

Arg: options

  • -n: 不輸出至 標準輸出 (預設是 each lines,通常配合pflag使用)
  • -i: edit file in-place,直接修改檔案
  • -E: 使用延伸正則表示式 (ERE,即不需跳脫 ?+|{(,但仍有例外)
  • -f: 執行 script file
  • -e script: 執行 -e 後的字串 (evaluate)

如果沒有指定 -e,第一個non-options的參數將會當成 script執行

Arg: script

script就是sed將執行的範圍和command的集合,表示法如下:

[addr1][,addr2]command[/pattern][/replacement]/[flags]

其中 addr (address) 代表作用行數 (位址) 範圍,例如 1-3 為 1,3, 5至資料末為5,$

事實上,address也可以用pattern matching來表示匹配的行數。例如

/^http:/,/^sftp:/

表示作用位址從**第一次匹配^http:的行數到最後一次匹配^sftp的行數範圍內。

sed 的 commands 則有許多種,常見如下:

  • d: 刪除指定位址,例如 sed '3,5d' 刪除 3-5 行
  • p: 印出指定行,通常和 -n option配合,sed '0,6p' 印出 0-6 行
  • a: 在指定行之下新增一行(各家實作有差異,略)
  • i: 在指定行之上插入一行(各家實作有差異,略)
  • s: 取代指定pattern,和vim取代類似。例如將2-8行內的**[Dd]og取代為cat**:
sed '2,8s/[Dd]og/cat/g'

command s (substitute) 常見的flag有:

  • p: 印出
  • g: 取代行內所有match occurrences,沒寫則只取代第一個
  • i: 忽略大小寫
  • 數字: 取代幾個occurrances

為了增加可讀性,scommand可替換分隔符號 (delimeter),接在s後的第一個字元即會成為分隔符。 例如下列會將所有匹配usr位址行數中的slash/取代為垂直線|,其中就將預設分隔符 / 替換成 :

cat /etc/passwd | sed '/usr/ /bin/ s:/:|:g'

Arg: inputfile

就是輸入資料,若讀取standard input,則可省略。

Reference

awk

awk 和其他 command line tool 差異較大,提供許多與 C 語言相近的語法,屬於小而巧的的直譯語言。預設情況下,awk 以空白 (white space) 作分隔符號 (delimeter),方便使用者取得特定欄位。

身為一種程式語言,awk 當然也可執行複雜的text processing,但直至今日 (2016.8),已有更強大的語言可以替代awk來處理文字 (e.g. perl & python)。不過,善用 awk 的 one-line command 結合 pipeline redirect,依然是快速有效的處理方式。在此也僅紀錄簡單常見的用法

使用時機:

處理格式化的表格、文字報表格式化輸出

Usage:

awk 'pattern { action }' [input-file ...]

Arg: 'pattern { action }'

理解 awk 之前,先看接下來的例子:

ls -l | awk 'FNR > 1 && FNR < 4 { print $3,$9 }'

# weihanglo Desktop
# weihanglo Documents

在bash的世界裡,雙引號內的字串會被interpolate,單引號中的內容中才會保留字面量。awk 為了防止預設欄位變數被取代,慣例上常將欲執行的程式寫在單引號' ... '

awk program 中的 pattern 作用如同 grep,篩選符合 pattern 的資料行,再繼續執行 { ... } 中的敘述。FNRawk內建的變數,> <awk的運算子 (operator),與 C 語言無異,以下列出常用的運算子及內建變數:

Operator Description
== 相等
!= 不相等
> 大於
>= 大於等於
< 小於
<= 小於等於
&& 且 (and)
`
~ 符合regex
!~ 不符合regex

而程式區塊 { ... } 則支援多種敘述 (statement),例如:for (var in array) ..print ...等。

Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment