1. 程式人生 > 實用技巧 >SHELL-文字編輯三劍客(grep|sed|awk)

SHELL-文字編輯三劍客(grep|sed|awk)

awk、grep、sed是linux操作文字的三大利器,合稱文字三劍客,也是必須掌握的linux命令之一。三者的功能都是處理文字,但側重點各不相同,其中屬awk功能最強大,但也最複雜。grep更適合單純的查詢或匹配文字,sed更適合編輯匹配到的文字,awk更適合格式化文字,對文字進行較複雜格式處理。

正則表示式

正則表示式可以使用正則表示式引擎實現,正則表示式引擎是解釋正則表示式模式並使用這些模式匹配文字的基礎軟體。

在Linux中,常用的正則表示式有:

  • POSIX 基本正則表示式(BRE)引擎
  • POSIX 擴充套件正則表示式(ERE)引擎

基本元字元

元字元 功能 示例
^ 行首定位法 ^love
$ 行尾定位法 love$
. 匹配單個字元 l..o
* 匹配前導符0到多次 ab*love
.* 任意多個字元
[] 匹配指定範圍內一個字元 [Ll]ove
[ - ] 匹配自動範圍內的一個字元 [0-9a-z]ove
[^] 匹配不在指定組內字元 [^0-9a-z]ove
\ 轉移符 love.
< 詞首定位符 <love
> 詞尾定位符 love>
(..) 匹配稍後使用的字元的標籤 :% s/172.16.130.1/172.16.130.5/g:% s/(172.16.130.)1/\15/:% s/(172.)(16.)(130.)1/\1\2\3
5/:3,9 s/(.*)/#\1/ 3-9行註釋掉
x{m} 字元X重複出現M次 o{5}
x{m,} 字元X重複出現M次以上 o{5,}
x{m,n} 字元X重複出現M-N次 o{5,10}

擴充套件元字元

元字元 功能 示例
+ 匹配一個或多個前導符 [a-z]+ove
? 匹配零個或一個前導符 lo?v3
a|b 匹配a或b love|hate
() 組字元
(..)(..)\1\2 標籤匹配字元 (love)able\1er
x{m} 字元X重複出現M次 o{5}
x{m,} 字元X重複出現M次以上 o{5,}
x{m,n} 字元X重複出現M-N次 o{5,10}

POSIX字元類

表示式 功能 示例
[:digit:] 任何數字
[:xdigit:] 任何十六進位制數字
[:alpha:] 任何字母
[:lower:] 任何小寫字母
[:upper:] 任何大寫字母
[:alnum:] 任何字母或數字
[:cntrl:] ASCII控制字元(ASCII 0~31 和 ASCII 127)
[:punct:] 不屬於[:alnum:]和[:cntrl:]的任何字元
[:blank:] 空格或製表符([\t ])
[:space:] 任何空白字元,包括換行符,回車符等在內的所有空白([\f\n\r\t\v ])
[:print:] 任何可列印字元
[:graph:] 同[:print:],但不包括空格

演示案例

# 1. 空行
/^$/
/^[ \t]*$/   # 開頭0個或多個空格或字元表結尾

# 2. 註釋行
/^#/
/^[ \t]*#/   # 0個或多個空格或字元表開頭後#號

grep

grep簡介

  Linux系統中grep命令是一種強大的文字搜尋工具,它能使用正則表示式搜尋文字,並把匹配的行打印出來。grep全稱是Global Regular Expression Print,表示全域性正則表示式版本,它的使用許可權是所有使用者。

  grep的工作方式是這樣的,它在一個或多個檔案中搜索字串模板。如果模板包括空格,則必須被引用,模板後的所有字串被看作檔名。搜尋的結果被送到標準輸出,不影響原檔案內容。

grep通過返回一個狀態值來說明搜尋的狀態

  • 如果搜尋成功,則返回0
  • 如果搜尋不成功,則返回1
  • 如果搜尋的檔案不存在,則返回2

egrep = grep -E:擴充套件的正則表示式

fgrep: fixed grep |fast grep

使用grep

命令格式

# 用法:
grep [選項] 模式 filename filename....

Usage: grep [OPTION]... PATTERN [FILE]...
Search for PATTERN in each FILE or standard input.
PATTERN is, by default, a basic regular expression (BRE).
Example: grep -i 'hello world' menu.h main.c

Regexp selection and interpretation:
  -E, --extended-regexp     PATTERN is an extended regular expression (ERE)
  -F, --fixed-strings       PATTERN is a set of newline-separated fixed strings
  -G, --basic-regexp        PATTERN is a basic regular expression (BRE)
  -P, --perl-regexp         PATTERN is a Perl regular expression
  -e, --regexp=PATTERN      use PATTERN for matching
  -f, --file=FILE           obtain PATTERN from FILE
  -i, --ignore-case         ignore case distinctions
  -w, --word-regexp         force PATTERN to match only whole words
  -x, --line-regexp         force PATTERN to match only whole lines
  -z, --null-data           a data line ends in 0 byte, not newline

Miscellaneous:
  -s, --no-messages         suppress error messages
  -v, --invert-match        select non-matching lines
  -V, --version             display version information and exit
      --help                display this help text and exit

Output control:
  -m, --max-count=NUM       stop after NUM matches
  -b, --byte-offset         print the byte offset with output lines
  -n, --line-number         print line number with output lines
      --line-buffered       flush output on every line
  -H, --with-filename       print the file name for each match
  -h, --no-filename         suppress the file name prefix on output
      --label=LABEL         use LABEL as the standard input file name prefix
  -o, --only-matching       show only the part of a line matching PATTERN
  -q, --quiet, --silent     suppress all normal output
      --binary-files=TYPE   assume that binary files are TYPE;
                            TYPE is 'binary', 'text', or 'without-match'
  -a, --text                equivalent to --binary-files=text
  -I                        equivalent to --binary-files=without-match
  -d, --directories=ACTION  how to handle directories;
                            ACTION is 'read', 'recurse', or 'skip'
  -D, --devices=ACTION      how to handle devices, FIFOs and sockets;
                            ACTION is 'read' or 'skip'
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive
                            likewise, but follow all symlinks
      --include=FILE_PATTERN
                            search only files that match FILE_PATTERN
      --exclude=FILE_PATTERN
                            skip files and directories matching FILE_PATTERN
      --exclude-from=FILE   skip files matching any file pattern from FILE
      --exclude-dir=PATTERN directories that match PATTERN will be skipped.
  -L, --files-without-match print only names of FILEs containing no match
  -l, --files-with-matches  print only names of FILEs containing matches
  -c, --count               print only a count of matching lines per FILE
  -T, --initial-tab         make tabs line up (if needed)
  -Z, --null                print 0 byte after FILE name

Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM
      --group-separator=SEP use SEP as a group separator
      --no-group-separator  use empty string as a group separator
      --color[=WHEN],
      --colour[=WHEN]       use markers to highlight the matching strings;
                            WHEN is 'always', 'never', or 'auto'
  -U, --binary              do not strip CR characters at EOL (MSDOS/Windows)
  -u, --unix-byte-offsets   report offsets as if CRs were not there
                            (MSDOS/Windows)

'egrep' means 'grep -E'.  'fgrep' means 'grep -F'.
Direct invocation as either 'egrep' or 'fgrep' is deprecated.
When FILE is -, read standard input.  With no FILE, read . if a command-line
-r is given, - otherwise.  If fewer than two FILEs are given, assume -h.
Exit status is 0 if any line is selected, 1 otherwise;
if any error occurs and -q is not given, the exit status is 2.

命令引數

選項 說明
-E 開啟擴充套件(Extend)的正則表示式,相當於egrep。
-i 忽略大小寫(ignore case)。
-v 只打印沒有匹配的行
-n 顯示匹配的行號
-w 被匹配的文字只能是單詞,而不能是單詞中的某一部分
-c 統計匹配的行數,而不是顯示被匹配到的內容
-e 實現多個選項的匹配,邏輯or關係
-q 靜默模式,不輸出任何資訊
-s 不顯示不存在或無匹配文字的錯誤資訊。
-R,-r 查詢遞迴目錄下的所有檔案
-o 只顯示被模式匹配到的字串。
--color 將匹配到的內容以顏色高亮顯示。
-A n 顯示匹配到的字串所在的行及其後n行,after
-B n 顯示匹配到的字串所在的行及其前n行,before
-C n 顯示匹配到的字串所在的行及其前後各n行,context上下文
-f FILE 從FILE獲取PATTERN匹配
-F 相當於fgrep

grep 使用的元字元

  • grep : 使用基本元字元 ^,$,.,*,[],[^],{},\<,\>,\(\),\+,\|

  • egrep(或grep -E): 使用的擴充套件元字元 +,?,{},|,()

注:grep也可以使用擴充套件元字元,僅需要加上前置反射線

元字元 功能 示例
\w 所有字母與數字, 字元[a-zA-Z0-9] 'b[a-zA-Z0-9]ao''b\wao'
\W 所有字母與數字之外的字元,稱為非字元 'biao[^a-zA-Z0-9]+''biao\W+'
\b 詞邊界 grep '\broot\b' /etc/passwdgrep '<love>' filename

grep實戰演示

# 在file檔案中過濾掉字串'str'所在的行
grep -v "str" file
# 在file檔案中查詢時間在2017:22:50~2017:22:59所在的行
grep -E "2017:22:5[0-9]" file 
# 在file檔案中查詢不包括360的行
grep -E "^[^360]" file 
# 在file檔案中查詢包括w和t的行
grep -E "w*t" file
# 在file檔案中查詢大於560小於893的行
grep -E "[5-8][6-9][0-3]" file
# 在file檔案中查詢包含兩個9的行
grep -E "9{2}" file
# 查詢大於兩個9的行
grep -E "9{2,}" file 
# 查詢file檔案中的空行
grep -E "^$" file 
# 查詢包括?的行
grep "?" file 
# 查詢檔案中以w開頭的行
grep -E "^w" file 
# 查詢檔案中不是以w開頭的行
grep -E "^[^w]" file

sed

sed 簡介

sed 是一種非互動式的行編輯器。

地址(定址):用於決定對哪些行進行編輯。地址形式可以是數字、正則表示式或二者的組合。如果沒有指定地址,預設處理輸入檔案中的所有行。

sed 工作過程

sed 編輯器逐行處理檔案(或輸入),並將輸出結果傳送到螢幕。

sed 把當前正在處理的行儲存在一個臨時快取區中,這個快取區稱為模式空間(PATTERN SPACE)或臨時緩衝。它在模式空間中進行處理,完成處理後,把緩衝區的內容輸出。接著處理下一行,直到檔案末尾。

如圖 1: sed 處理過程。

sed 命令格式

Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...

  -n, --quiet, --silent
                 suppress automatic printing of pattern space
  -e script, --expression=script
                 add the script to the commands to be executed
  -f script-file, --file=script-file
                 add the contents of script-file to the commands to be executed
  --follow-symlinks
                 follow symlinks when processing in place
  -i[SUFFIX], --in-place[=SUFFIX]
                 edit files in place (makes backup if SUFFIX supplied)
  -c, --copy
                 use copy instead of rename when shuffling files in -i mode
  -b, --binary
                 does nothing; for compatibility with WIN32/CYGWIN/MSDOS/EMX (
                 open files in binary mode (CR+LFs are not treated specially))
  -l N, --line-length=N
                 specify the desired line-wrap length for the `l' command
  --posix
                 disable all GNU extensions.
  -r, --regexp-extended
                 use extended regular expressions in the script.
  -s, --separate
                 consider files as separate rather than as a single continuous
                 long stream.
  -u, --unbuffered
                 load minimal amounts of data from the input files and flush
                 the output buffers more often
  -z, --null-data
                 separate lines by NUL characters
  --help
                 display this help and exit
  --version
                 output version information and exit

sed的常用選項

選項 功能說明
-n 取消預設的輸出
-e 多重編輯,且命令順序會影響結果
-f 指定一個 sed 指令碼檔案到命令列執行,
-r sed 使用擴充套件正則
-i 直接修改文件讀取的內容,不在螢幕上輸出

sed 操作命令

sed 操作命令告訴 sed 對指定行進行何種操作,包括列印、刪除、修改等

命 令 說 明
a\ 在當前行後新增一行或多行
c 用新文字修改(替換)當前行中的文字
d 刪除行
i 在當前行之前插入文字
h 把模式空間裡的內容複製到暫存快取區(覆蓋
H 把模式空間裡的內容追加到暫存快取區
g 取出暫存緩衝區裡的內容,將其複製到模式空間,覆蓋該處原有內容
G 取出暫存緩衝區裡的內容,將其複製到模式空間,追加在原有內容後面
l 列出非列印字元
p 列印行
n 讀入下一輸入行,並從下一條命令而不是第一條命令開始處理
q 結束或退出 sed
r 從檔案中讀取輸入行
對所選行意外的所有行應用命令
s 用一個字串替換另一個
w 將行寫入檔案
x 交換暫存緩衝區與模式空間的內容
y 將字元轉換為另一字元(不能對正則表示式使用 y 命令)

替換標誌

緊跟在 s 命令後的字元就是查詢串和替換串之間的分隔符。分隔符預設為正斜槓

s 替換標識
g 在行內進行全域性替換
i 忽略大小寫

sed 的正則表示式

基本元字元: ^,$,.,*,[],[^],\{\},\<,\>,\(\),&

元字元 功 能 示 例 示例的匹配物件
^ 行首定位符 /^love/ 匹配所有以 love 開頭的行
$ 行尾定位符 /love$/ 匹配所有以 love 結尾的行
. 匹配除換行外的單 個字元 /l..e/ 匹配包含字元 l後跟兩個任意字元、再跟字母 e 的行
* 匹配零個或多個前 導字元 /*love/ 匹配在零個或多個空格緊跟著模式 love 的行
[] 匹配指定字元組內 任一字元 /[Ll]ove/ 匹配包含 love 和 Love 的行
[^] 匹配不在指定字元 組內任一字元 /[^A-KM-Z]ove/ 匹配包含 ove,但 ove 之前的那 個字元不在 A 至 K 或 M 至 Z 間 的行
\(..\) 儲存已匹配的字元
& 儲存查詢串以便在 替換串中引用 s/love/**&**/ 符號&代表查詢串。字串 love 將替換前後各加了兩個**的引 用,即 love 變成**love**
\< 詞首定位符 /<love/ 匹配包含以 love 開頭的單詞的 行
\> 詞尾定位符 /love>/ 匹配包含以 love 結尾的單詞的 行
x\{m\} 連續 m 個 x /o{5}/ 匹配出現連續 5 個字母 o的行
x\{m,\} 至少 m 個 x /o{5,}/ 匹配出現至少 5 個連續的 o 的行
x\{m,n\} 至少 m 個 x,但不 超過 n 個 x /o{5,10}/ 匹配出現 5~10 個連續的 o 的行

擴充套件元字元

-r選項即可使用擴充套件元字元

 sed --help|grep '\-r'
  -r, --regexp-extended

擴充套件元字元 +,?,{},|,()

sed使用例項

刪除: d 命令

命令 d 用於刪除輸入行。sed 先將輸入行從檔案複製到模式快取區,然後對該行執行 sed命令,最後將模式快取區的內容顯示在螢幕上。如果發出的是命令 d,當前模式快取區的輸入行會被刪除,不被顯示。

sed -r '3d' datafile    # 刪除第3行,其餘各行被列印。
sed -r '3{d;}' datafile # 刪除第3行,其餘各行被列印。
sed -r '3{d}' datafile  # 刪除第3行,其餘各行被列印。

sed -r '3,$d' datafile  # 刪除從第三行到最後一行內容,其餘各行被列印。
sed -r '$d' datafile    # 刪除最後一行內容,其餘各行被列印。
sed -r '/north/d' datafile # 所有包含模式 north 的行都被動刪除,其餘行被列印。

替換: s 命令

命令 s 是替換命令。替換和取代檔案中的文字可以通過 sed 中的 s 來實現, s 後包含在斜槓中的文字是正則表示式,後面跟著的是需要替換的文字。可以通過 g 標誌對行進行全域性替換

說明:緊跟在 s 命令後的字元就是查詢串和替換串之間的分隔符。分隔符預設為正斜槓,但可以改變。無論什麼字元(換行符,反斜線除外),只要緊跟在 s 命令,就成了新的串分隔符。

sed 's/west/north/g' datafile             # 替換每行中west為north
sed -n 's/^west/north/p' datafile         # 選線-n 與命令列末尾的標誌 p 結合,告訴 sed 只打印發生替換的那些行;也就是說,如果只有在行首找到 west 並替換成 north 時才會列印此行。
sed 's/[0-9][0-9]$/&.5/' datafile         # 所有以 2 位數結尾的行後面都被加上.5
sed -n 's/Hemenway/Jones/gp' datafile     # 檔案中出現的所有的 Hemenway 都被替換為 Jones,只有發生變化的行才會打印出來。選項-n 與命令 p 的組合取消了預設的輸出。標誌 g 的含義是表示在行內全域性替換。
sed 's/\(Mar\)got/\1linanne/g' datafile   # 包含在圓括號裡的模式 Mar 作為標籤 1 儲存在特定的暫存器中。替換串可以通過\1 來引用它。則 Margot 被替換為 Marlinanne
sed -r 's/(Mar)got/\1linanne/g' datafile  # 同上
sed 's#3#88#g' datafile                   # 替換每行中3為88

指定行的範圍:逗號

行的範圍從檔案中的一個地址開始,在另一個地址結束。地址範圍可以是行號(例如5,10),正則表示式(例如/Dick/和/Joe/),或者兩者的結合(例如/north/,$)範圍是閉合的——包含開始條件的行,結束條件的行,以及兩者之間的行。如果結束條件無法滿足,就會一直操作到檔案結尾。如果結束條件滿足,則繼續查詢滿足開始條件的位置,範圍重新開始。

sed -n '/west/,/east/p' datafile           # 列印模式匹配 west 與 east或檔案的末尾(east未匹配到)之間所有的行
sed -n '5,/northeast/p' datafile           # 列印從第5行開始到第一個匹配northeast行之間的所有行
sed '/west/,/east/s/$/**VACA**/' datafile  # 修改從模式 wast 和 east 之間的所有行,將各行的行尾($)替換為字串**VACA**。換行符被移到新的字串後面。

多重編輯: e 命令

-e 命令是編輯命令,用於 sed 執行多個編輯任務的情況下。在下一行開始編輯前,所有的編輯動作將應用到模式快取區的行上。

sed -r -e '1,3d' -e 's/Hemenway/Jones/' datafile  #
sed -r '1,3d;s/Hemenway/Jones/' datafile  #

說明:選項-e 用於進行多重編輯。第一重編輯編輯刪除第 1~3 行。第二重編輯將Hemenway 替換為 Jones。因為是逐行進行這兩行編輯(即這兩個命令都在模式空間的當前行上執行),所以編輯命令的順序會影響結果。例如,如果兩條命令都執行的是替換,前一次替換會影響後一次替換。

追加: a 命令

a 命令是追加命令,追加將新文字到檔案中當前行(即讀入模式的快取區行)的後面。不管是在命令列中,還是在 sed 指令碼中, a 命令總是在反斜槓的後面。

sed '/^north/a Hello world!' datafile

說明:命令 a 用於追加。字串 Hello, World!被加在以 north 開頭的各行之後。如果要追加的內容超過一行,則除最後一行外,其他各行都必須以反斜槓結尾。

插入: i 命令

i 命令是插入命令,類似於 a 命令,但不是在當前行後增加文字,而是在當前行前面插入新的文字,即剛讀入快取區模式的行。

sed '/eastern/i Hello,world!' datafile

說明:命令 i 是插入命令。如果在某一行匹配到模式 eastern,i 命令就在該行的上方插入

修改: c 命令

c 命令是修改命令。 sed 使用該命令將已有的文字修改成新的文字。舊文字被覆蓋。

sed -r '/eastern/c Hello,world!' datafile # 如果模式 eastern被匹配, c 命令將其後的文字替換包含 eastern 的行。

獲取下一行: n 命令

n 命令表示下一條命令。 sed 使用該命令獲取輸入檔案的下一行,並將其讀入到模式緩衝區中,任何 sed 命令都將應用到匹配行,緊接著的下一行上。

sed -r '/eastern/{ n;d }' datafile # 刪除匹配到模式 eastern的下一行
sed -r '/eastern/{ n;s/AM/Archie/ }' datafile # 如果在某一行匹配到模式 eastern, n 命令就指示 sed 用下一個輸入行用 Archie 替換 AM,然後列印該行,再繼續往下處理

轉換: y,命令

y 命令表示轉換。該命令與 tr 命令相似,字元按照一對一的方式從左到右進行轉換。例如 y/abc/ABC/,會把小寫字母轉換成大寫字母, a-->A,b-->B,c-->C。

sed '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' datafile 

y 命令把 1~3 行中所有的小寫命令字母都轉換成了大寫。正則表示式元字元對 y 命令不起作用。與替分隔符一樣,斜槓可以被替換成其他字元。

退出: q 命令

q 命令表示退出命令。該命令將導致 sed 程式退出,且不再進行其他的處理。

sed '5q' datafile # 列印完第5行之後, q 讓 sed 程式退出

sed '/Lewis/{ s/Lewis/Joseph/;q; }' datafile # 在某行匹配到模式 Lewis 時, s 表示先用 Joseph 替換 Lewis,然後 q 命令讓 sed 退出

暫存和取用命令: h H g G

  • h把模式空間裡的內容複製到暫存快取區(覆蓋
  • H把模式空間裡的內容追加到暫存快取區
  • g取出暫存緩衝區裡的內容,將其複製到模式空間,覆蓋該處原有內容
  • G取出暫存緩衝區裡的內容,將其複製到模式空間,追加在原有內容後面
sed -r '1h;$G' datafile        # 將第1行內容追加到檔案最後一行
sed -r '1{h;d};$G' datafile    # 將第一行復制到暫存空間並刪除,取出暫存空間內容追加到最後一行
sed -r '1h; 2,$g' datafile     # 將第一行復制到暫存空間,取出暫存緩衝區裡的內容覆蓋第2行至最後一行的內容
sed -r '1h; 2,3H; $G' datafile # 將第1至3行復制到暫存空間並追加到最後一行

暫存空間和模式空間互換命令:x

sed -r '4h; 5x; 6G' datafile # 將第4行復制到暫存空間,處理第5行時,交換暫存空間內容和模式空間,第6行追加暫存空間內容(即將第4行內容覆蓋第5行,並將原第5行追加到第6行後)

反向選擇:!

sed -r '3d' datafile  # 刪除第3行,列印其餘行
sed -r '3!d' datafile # 只輸出第3行

綜合案例

刪除空格、空行、帶“ #”開頭的註釋行

# 刪除配置檔案中#號註釋行
sed -ri '/^[ \t]*#/d' file  

# 刪除配置檔案中//號註釋行
sed -ri '\Y^[ \t]*//Yd' file #指定Y分隔符
sed -ri '\#^[ \t]*//#d' file

# 刪除空行
sed -ri '/^[ \t]*$/d' file

# 刪除#號註釋行和空行
sed -ri '/^[ \t]*#/d;/^[ \t]*$/d' file
sed -ri '/^[ \t]*#|/^[ \t]*$/d' file
sed -ri '/^[ \t]*($|#)/d' file

修改檔案

# 檔案最後一行追加chroot_local_user=YES
sed -ri '$a\chroot_local_user=YES' file

# 模式匹配行首為SELINUX=的行替換為 SELINUX=disabled
sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config

sed -ri '/UseDNS/cUseDNS no' /etc/ssh/sshd_config
sed -ri '/GSSAPIAuthentication/cGSSAPIAuthentication no' /etc/ssh/sshd_config

給檔案添加註釋符#號

# 從第2至4行的行首新增#號
sed -r '2,4s/^/#' file 
sed -r '2,4s/(.*)/#\1/' file
sed -r '2,4s/.*/#&/' file  # &匹配前面查詢的內容

sed -r '3,$ s/^#*/#/' file
sed -r '30,50s/^[ \t]*#*/#/' file
sed -r '2,8s/^[ \t#]*/#/' file

使用外部變數

var1=11111
sed -ri "3a$var1" file    # 第3行後追加變數var1的內容
sed -ri 3a$var1 file      # 第3行後追加變數var1的內容

sed -ri '$a\'"$var1" file # 最後一行後追加變數var1的內容
sed -ri "\$a$var1" file   # 最後一行後追加變數var1的內容

檔案內容行倒序輸出

sed -r '1!G; $!h; $!d' file
sed -r '1!G;h;$!d' file

1!G:表示第一行不執行G命令,其它行執行G命令(取出暫存緩衝區裡的內容,將其複製到模式空間,追加在原有內容後面)

$!d:最後一行不刪除

  • P 代表模式空間

  • H 代表暫存緩衝區

  • 綠色 代表模式空間中的資料

  • 藍色 代表暫存緩衝區中的資料

awk

awk簡介

  awk是一種程式語言,用於在linux/unix下對文字和資料進行處理。資料可以來自標準輸入(stdin)、一個或多個檔案,或其它命令的輸出。它支援使用者自定義函式和動態正則表示式等先進功能,是linux/unix下的一個強大程式設計工具。它在命令列中使用,但更多是作為指令碼來使用。awk有很多內建的功能,比如陣列、函式等,這是它和C語言的相同之處,靈活性是awk最大的優勢。

  awk其實不僅僅是工具軟體,還是一種程式語言。

工作原理

  • 依次把匹配到的行,使用awk工具進行編輯

  • $0表示整行,$1代表第一個…,$NF代表最後一個

  • pattern: 通過模式匹配對應的欄位過濾行

  • 通過對應的命令 printf 做格式化輸出

使用awk

語法

awk [options] 'program' var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...


Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:		GNU long options: (standard)
	-f progfile		--file=progfile
	-F fs			--field-separator=fs
	-v var=val		--assign=var=val
Short options:		GNU long options: (extensions)
	-b			--characters-as-bytes
	-c			--traditional
	-C			--copyright
	-d[file]		--dump-variables[=file]
	-e 'program-text'	--source='program-text'
	-E file			--exec=file
	-g			--gen-pot
	-h			--help
	-L [fatal]		--lint[=fatal]
	-n			--non-decimal-data
	-N			--use-lc-numeric
	-O			--optimize
	-p[file]		--profile[=file]
	-P			--posix
	-r			--re-interval
	-S			--sandbox
	-t			--lint-old
	-V			--version

To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.

gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.

Examples:
	gawk '{ sum += $1 }; END { print sum }' file
	gawk -F: '{ print $1 }' /etc/passwd

  

常用命令選項

  • -F fs:fs指定輸入分隔符,fs可以是字串或正則表示式,如-F:
  • -v var=value:賦值一個使用者定義變數,將外部變數傳遞給awk
  • -f scripfile:從指令碼檔案中讀取awk命令

awk變數

變數:內建和自定義變數,每個變數前加 -v 命令選項

內建變數

格式
  • FS :輸入欄位分隔符,預設為空白字元

  • OFS :輸出欄位分隔符,預設為空白字元

  • RS :輸入記錄分隔符,指定輸入時的換行符,原換行符仍有效

  • ORS :輸出記錄分隔符,輸出時用指定符號代替換行符

  • NF :欄位數量,(讀取的列數) $NF引用最後一列,$(NF-1)引用倒數第2列

  • NR :行號,後可跟多個檔案,第二個檔案行號繼續從第一個檔案最後行號開始

  • FNR :各檔案分別計數, 行號,後跟一個檔案和NR一樣,跟多個檔案,第二個檔案行號從1開始

  • ARGC :命令列引數的個數

  • ARGV :陣列,儲存的是命令列所給定的各引數,檢視引數

欄位分隔符: FS OFS 預設空格或製表符

記錄分隔符:RS ORS 預設換行符