2012/08/26

Linux 的文字處理與正規表示式(sed , RE)


文字處理

觀看文字檔案內容

cat
列出文字檔內容
cat file | grep "string" | more 常與grep合用
less
觀看文字檔內容,但可上下跳頁及搜尋。
可觀看 .gz and .bz2的檔案
/text 搜尋 text 內容
n/N 跳到 下一個或上一個搜尋到的
v 打開一個檔案
head
從檔案開頭觀看指定行數內容,如不指定預設為10行
-n 可以決定要看幾行
tail
tail -f 觀看目前即時的檔案內容
-n 可以決定要看幾行
linux:~ # cd ~
linux:~ # touch aaa
linux:~ # ls aaa -la
-rw-r--r--  1 root root 0 2006-09-03 13:07 aaa
linux:~ # touch aaa
linux:~ # ls aaa -la
-rw-r--r--  1 root root 0 2006-09-03 13:09 aaa
mtchang@web:~$ cd /var/log
mtchang@web:/var/log$ su
Password:
web:/var/log# tail /var/log/messages -n 10
May 22 12:33:57 web -- MARK --
May 22 12:53:57 web -- MARK --
May 22 13:13:57 web -- MARK --
May 22 13:33:57 web -- MARK --
May 22 13:53:57 web -- MARK --
May 22 14:13:57 web -- MARK --
May 22 14:33:57 web -- MARK --
May 22 14:53:57 web -- MARK --
May 22 15:13:57 web -- MARK --
May 22 15:33:57 web -- MARK --
搜尋檔案內容

使用grep命令
mtchang@web:~$  grep [-acinv] '搜尋字串' filename
選項說明:
-a :將 binary 檔案以 text 檔案的方式搜尋資料
-c :計算找到 '搜尋字串' 的次數
-i :忽略大小寫的不同,所以大小寫視為相同
-n :順便輸出行號
-v :反向選擇,亦即顯示出沒有 '搜尋字串' 內容的那一行!
範例:
mtchang@web:~$ grep '.tw' xferlog
# 把xferlog檔案中帶有.tw字串的列印出來
mtchang@web:~$ grep -v '.tw' xferlog
# 把xferlog檔案中不帶有.tw字串的列印出來
mtchang@web:~$ grep -c '.tw' xferlog
# 計算搜尋到字串得次數
mtchang@web:~$ grep -n '.tw' xferlog
# 輸出行號
mtchang@web:~$ grep -ic '.tw' xferlog
# 計算搜尋到字串得次數,忽略大小寫
grep和egrep
egrep是grep的擴充命令,他提供更完整的extended regular expressions(正規表示式)
列的擷取cut

cut用法
[root@localhost log]# cut --help
用法:cut [選項]... [檔案]...
在標準輸出中顯示每個 <檔案> 每一行中指定的部份。
長選項必須用的參數在使用短選項時也是必須的。
  -b, --bytes=LIST        只顯示指定的位元組
  -c, --characters=LIST   只顯示指定的字元
  -d, --delimiter=DELIM   以 DELIM 字元代替 TAB 作為欄位的分隔符號
  -f, --fields=LIST       select only these fields;  also print any line
                            that contains no delimiter character, unless
                            the -s option is specified
  -n                      with -b: don't split multibyte characters
      --complement        complement the set of selected bytes, characters
                            or fields.
  -s, --only-delimited    不印出不含分隔符號的每一行
      --output-delimiter=字串  以 <字串> 作為輸出資料的分隔符號
                               預設是使用輸入資料的分隔符號
Display specific columns of file or STDIN data
$ cut -d: -f1 /etc/passwd
$ grep root /etc/passwd | cut -d: -f7
Use -d to specify the column delimiter (default is TAB)
Use -f to specify the column to print
Use -c to cut by characters
$ cut -c2-5 /usr/share/dict/words
# 顯示目前的本機上得使用者帳號
[lcc09@localhost ~]$ cut -d: -f1 /etc/passwd
擷取目前電腦ip
debian:~# ifconfig
eth1      Link encap:Ethernet  HWaddr 00:14:85:2C:66:26 
          inet addr:192.168.1.50  Bcast:255.255.255.255  Mask:255.255.255.0
          inet6 addr: fe80::214:85ff:fe2c:6626/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:42155 errors:0 dropped:0 overruns:0 frame:0
          TX packets:49858 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:44901062 (42.8 MiB)  TX bytes:6941630 (6.6 MiB)
          Interrupt:177

lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:120 errors:0 dropped:0 overruns:0 frame:0
          TX packets:120 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:12678 (12.3 KiB)  TX bytes:12678 (12.3 KiB)

debian:~# ifconfig | grep 'inet addr'
          inet addr:192.168.1.50  Bcast:255.255.255.255  Mask:255.255.255.0
          inet addr:127.0.0.1  Mask:255.0.0.0
debian:~# ifconfig | grep 'inet addr' | cut -d: -f2
192.168.1.50  Bcast
127.0.0.1  Mask
debian:~# ifconfig | grep 'inet addr' | cut -d: -f2 | cut -d' ' -f1
192.168.1.50
127.0.0.1
練習1:把 ifconfig 的 HWaddr (MAC address) 資料抓出來。
skip...
mac find 可以找出 mac address 所屬註冊公司http://www.coffer.com/mac_find/
關於 mac address http://en.wikipedia.org/wiki/MAC_address
練習2:請以上個章節的 num.sh 檢測目前網段的機器的程式為基礎,將輸出結果作處理。
底下為 ping 過程中的輸出畫面,第一個為成功的結果,第二個為失敗的結果

[root@server1 class]# ping 192.168.3.1 -c 1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq=1 ttl=255 time=0.418 ms

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.418/0.418/0.418/0.000 ms
[root@server1 class]# ping 192.168.3.3 -c 1
PING 192.168.3.3 (192.168.3.3) 56(84) bytes of data.
From 192.168.3.250 icmp_seq=1 Destination Host Unreachable

--- 192.168.3.3 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
請寫一個 shell script 使用將 min/avg/max/mdev及 packet loss 的數值取出,並且以類似底下的方式呈現輸出:
host,min,avg,max,mdev,packet lost
192.168.3.1,0.140,0.149,0.154,0.006,0%
192.168.3.2,0,0,0,0,100%
作業請回文於討論區(2010.10.31更新):http://expert.lccnet.com.tw/zone/viewthread.php?tid=22193
find

find
語法 find [path] [criterion] [action]
基本上可以分成三個大項來看:
搜尋路徑
搜尋的檔案條件,支援"正則表示式"的語法。
動作action
命令執行(exec),屬"附加"性質,讓我們可以直接對 find 找到的檔案,運作指定的外部指令。
列印顯示(print),支援固定顯示。也可將顯示的資訊藉由選項直接存檔。
選項說明
-daystart 起始時間以當日的 -amin, -atime, -cmin, -ctime, -mmin, 及 -mtime 為基準。
-depth 處理目錄內容之後,再處理目錄本身。
-follow 對符號連結的檔案或目錄不做檢查。隱含了 -noleaf 選項的作用。
-help, --help 顯示程式用法資訊。
-maxdepth levels 指定搜尋測試的最大目錄層數(levels)。對超過目錄層數的子目錄將不予以處理。
-mindepth levels 指定搜尋測試的最小目錄層數(levels)。對 levels 內的目錄層數將不予以處理。
-mount 只處理當前所在的檔案系統。不處理不同檔案系統(filesystems)的目錄。此選項在某些版本的 find 指令必須改用 -xdev 選項。
-noleaf 捨棄檢查目錄是否有兩個硬連結(hard link)的優化處理。(程式預設的優化處理,在不必要時,反而會減緩搜尋測試的速度。如果使用者能理解自己檔案系統的硬連結狀況,適當地關閉預設的優化處理,將有助於速度的提昇)
-version, --version 顯示程式本身的版本資訊。
-xdev 只處理當前所在的檔案系統。對放置在不同檔案系統(filesystems)的目錄不做處理。
[root@server1 ~]# find /etc -name 'ifcfg*' -type f
# 找出檔名為ifcfg* 只列出type為f形式的資料
/etc/sysconfig/networking/profiles/default/ifcfg-eth0.bak
/etc/sysconfig/networking/profiles/default/ifcfg-eth0
/etc/sysconfig/networking/devices/ifcfg-eth0.bak
/etc/sysconfig/networking/devices/ifcfg-eth0
/etc/sysconfig/network-scripts/ifcfg-eth0.bak
/etc/sysconfig/network-scripts/ifcfg-lo
/etc/sysconfig/network-scripts/ifcfg-eth0

[root@server1 ~]# find /etc -name 'n*' -type d
# 找出檔名為 n* 只列出type為d形式的資料
/etc/pki/nssdb
/etc/sysconfig/networking
/etc/sysconfig/network-scripts
/etc/netplug
/etc/netplug.d
/etc/ntp

# 找出 /etc 目錄下檔名為ifcfg* 只列出type為f形式的資料,把他複製到 ./backup 目錄下
[root@server1 ~]# find /etc -name 'ifcfg*' -type f -exec cp {} ./backup/ \;
[root@server1 ~]# ls backup/
ifcfg-eth0  ifcfg-eth0.bak  ifcfg-lo  sysconfig-20090321

# 找出 /etc 目錄下檔名為ifcfg* 只列出type為f形式的資料,搜尋檔案內容帶有 eth0 字串的
[root@server1 ~]# find /etc -name 'ifcfg*' -type f -exec grep 'eth0' {}  \;
DEVICE=eth0
DEVICE=eth0
DEVICE=eth0
DEVICE=eth0
DEVICE=eth0
DEVICE=eth0
練習:
找出 /home 目錄下附檔名為 .mp3 , .avi . wmv 的檔案,把它複製到 /root/backup 目錄後,並把他刪除。
....wait..
文字分析工具

wc

文字狀態: wc
[lcc09@localhost ~]$ wc --help
用法:wc [選項]... [檔案]...
印出每個 <檔案> 的行數、字數及位元組數目,指定多個 <檔案> 時還會印出總計。
如果沒有指定 <檔案> 或 <檔案> 是 -,則由標準輸入讀取資料。
  -c, --bytes            印出位元組數目
  -m, --chars            印出字元數目
  -l, --lines            印出行數
  -L, --max-line-length  印出最長一行的字數
  -w, --words            印出以空格隔開為標準的字數
      --help     顯示此求助說明並離開
      --version  顯示版本資訊並離開

請向  回報錯誤。

[lcc09@localhost ~]$ wc .bash*
  52  107  733 .bash_history
   3    3   24 .bash_logout
  12   27  176 .bash_profile
   8   21  124 .bashrc
  75  158 1057 總計
debian:~# ls /tmp | wc -l
10
sort

排序文字: sort
[lcc09@localhost ~]$ sort --help
用法:sort [選項]... [檔案]...
Write sorted concatenation of all FILE(s) to standard output.

長選項必須用的參數在使用短選項時也是必須的。
Ordering options:

  -b, --ignore-leading-blanks  ignore leading blanks
  -d, --dictionary-order      consider only blanks and alphanumeric characters
  -f, --ignore-case           fold lower case to upper case characters
  -g, --general-numeric-sort  以普通數值的方式作比較
  -i, --ignore-nonprinting    只考慮可列印的字元
  -M, --month-sort            比較月份: (不明) <‘JAN’< ... <‘DEC’
  -n, --numeric-sort          將字串轉換為數值來作比較
  -r, --reverse               以相反的次序排列
...(略)

[lcc09@localhost ~]$ grep /bin/bash /etc/passwd
root:x:0:0:root:/root:/bin/bash
mtchang:x:500:500::/home/mtchang:/bin/bash
lcc09:x:501:100::/home/lcc09:/bin/bash
[lcc09@localhost ~]$ grep /bin/bash /etc/passwd | sort
lcc09:x:501:100::/home/lcc09:/bin/bash
mtchang:x:500:500::/home/mtchang:/bin/bash
root:x:0:0:root:/root:/bin/bash
debian:~# cut -d: -f7 /etc/passwd | sort | uniq
# 將/etc/passwd的第七個欄位排序,並且去除重複的。
/bin/bash
/bin/false
/bin/sh
/bin/sync
/usr/sbin/nologin
uniq

uniq指令可移除重覆的行
[mtchang@web ~]$ uniq --help
用法:uniq [選項]... [輸入 [輸出]]
將 <輸入> (預設為標準輸入) 的資料中每行連續相同的資料捨棄至只剩一行,
並在 <輸出> 顯示結果 (預設會在標準輸出顯示結果)。
長選項必須用的參數在使用短選項時也是必須的。
  -c, --count           每行前加上出現次數
  -d, --repeated        只印出重複的資料
  -D, --all-repeated[=分隔方式]
                        印出所有重複的資料
                        分隔方式={none(預設)、prepend、separate}
                        會使用空行來分隔資料。
  -f, --skip-fields=N   不比較最初的 N 個欄位
  -i, --ignore-case     比較時忽略大小寫
  -s, --skip-chars=N    不比較最初的 N 個字元
  -u, --unique          只印出沒有重複的資料
  -w, --check-chars=N   每行比較不多於 N 個字元
      --help     顯示此求助說明並離開
      --version  顯示版本資訊並離開
一個欄位是由一組空白字元加上一組非空白的字元組成的。
當同時指定略過欄位和略過字元不作比較時,會先略過欄位。
-c 參數 可以計算重複發生幾次
可以配合 sort 可以得到最佳效果
# 抓出 /etc/passwd 的第七個欄位
[mtchang@web ~]$ cut -d: -f7 /etc/passwd | sort | uniq
/bin/bash
/bin/sync
/sbin/halt
/sbin/nologin
/sbin/shutdown
# 去除並計算重複的欄位七
[mtchang@web ~]$ cut -d: -f7 /etc/passwd | sort | uniq -c
      1
    609 /bin/bash
      1 /bin/sync
      1 /sbin/halt
     34 /sbin/nologin
      1 /sbin/shutdown
文法拼字檢查: aspell

練習前請先建立一個範例檔案
底下這段文字其中,「develope」及「linux-based」在用法上有小錯誤,aspell啟動後會請你修正。
[lcc09@localhost ~]$ vi spell.txt
Ubuntu is a community develope, linux-based operating
system that is perfect for laptops,desktops and servers.
 it contains all the applications you need - a web browser
, presentation,document and spreadsheet software,
instant messaging and  much more.
執行aspell以lang=en的語系做檢查
[lcc09@localhost ~]$ aspell check -l en spell.txt
look 指令可以顯示接近的單字
[mtchang@web ~]$ look globb
globbier
globby
更多詳細的資訊,請見專案網站 aspell
字元的修改: tr

轉換字元從一個集合到另一個集合
使用範例
[lcc09@localhost ~]$ tr --help
用法:tr [選項]... SET1 [SET2]
Translate, squeeze, and/or delete characters from standard input,
writing to standard output.

  -c, -C, --complement    first complement SET1
  -d, --delete            delete characters in SET1, do not translate
  -s, --squeeze-repeats   replace each input sequence of a repeated character
                            that is listed in SET1 with a single occurrence
                            of that character
  -t, --truncate-set1     first truncate SET1 to length of SET2
      --help     顯示此求助說明並離開
      --version  顯示版本資訊並離開

SET 是以字串方式指定。大部份字元都會直接處理。要解譯的序列包括:

  \NNN            八進位數字 NNN (1 至 3 個位)所代表的字元
  \\              反斜號
  \a              響聲 (BEL)
  \b              倒退字元 (backspace)
  \f              換頁字元 (form feed)
  \n              換行字元 (new line)
  \r              復位字元 (return)
  \t              水平定位字元 (tab)
  \v              垂直定位字元 (vertical tab)
  字元1-字元2     由 <字元1> 開始升序排列至 <字元2>
  [字元*]         在 SET2 裡重複加上 <字元>,直至符合 SET1 的長度
  [字元*重複次數] 重複指定 <字元>,如果 <重複次數> 的第一個字元是 0 則表示
                  <重複次數> 是八進位數字
  [:alnum:]       所有英文字及數字
  [:alpha:]       所有英文字
  [:blank:]       所有水平的空白字元
  [:cntrl:]       所有控制字元
  [:digit:]       所有數字
  [:graph:]       所有可列印的字元,不包括空格
  [:lower:]       所有小寫英文字母
  [:print:]       所有可列印的字元,包括空格
  [:punct:]       所有標點符號
  [:space:]       所有水平或垂直的空白字元
  [:upper:]       所有大寫英文字母
  [:xdigit:]      所有十六進位數字
  [=CHAR=]        所有和 CHAR 同等的字元
...(略)...
大小寫轉換
[lcc09@localhost ~]$ tr 'a-z' 'A-Z' < spell.txt
另一種翻譯
[root@server1 ~]# echo '1234567' | tr '0-9' 'a-j'
bcdefgh
加上行號:nl

nl 指令可以替檔案加上行號,並輸出到 stdout
[mtchang@web ~]$ nl --help
用法:nl [選項]... [檔案]...
將每個 <檔案> 的內容在標準輸出顯示,並加上行號。
如果沒有指定 <檔案> 或 <檔案> 是 -,則由標準輸入讀取資料。

長選項必須用的參數在使用短選項時也是必須的。
  -b, --body-numbering=方式       決定將內容加上行號的 <方式>
  -d, --section-delimiter=CC      使用 CC 字元分辨標頭、內容和註腳
  -f, --footer-numbering=方式     決定將註腳加上行號的 <方式>
  -h, --header-numbering=方式     決定將標頭加上行號的 <方式>
  -i, --page-increment=數字       每行的行號增加量
  -l, --join-blank-lines=行數     將指定 <行數>的空行合併成一行
  -n, --number-format=格式        根據 <格式> 加上行號
  -p, --no-renumber               每次分頁後不重設行號
  -s, --number-separator=字串     以 <字串> 分隔行號和內容
  -v, --starting-line-number=數字 每頁第一行的行號
  -w, --number-width=數字         以指定 <數字> 的字元作為顯示行數的寬度
      --help     顯示此求助說明並離開
      --version  顯示版本資訊並離開
範例:
[mtchang@cccm ~]$ nl /etc/passwd
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6  sync:x:5:0:sync:/sbin:/bin/sync
     7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     8  halt:x:7:0:halt:/sbin:/sbin/halt
     9  mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
....(skip)
特殊的複合式搜尋處理

Regular Expression

Regular Expression(正規表示式) 是一種字串表達的方式.
使用者可使用一個簡短的 Regular Expression 來表示 〝具有某特徵〞 或者 〝複雜難以描述〞的所有字串。
正規表示式通常搭配指令或是其他程式運用,例如grep,sed,less等...
[普通字元] 除了``.、``[、``]、``*、``+、``?、 ``|、``^、``$、``{、``}、``\、 ``<、``>、``(、``) 外之所有字元.
由普通字元所組成的 Regular Expression 其意義與原字串字面意義相同. 例如 :
普通字元``A也可當成一個 Regular Expression. Regexp `` A 與一般字元``A代表相同的意義.
Regexp `` the 與一般字串``the代表相同的意義.
[ .] Metacharacter 用以代表任意一個字元. 須留心 UNIX Shell 中使用``?表示任意一個字元, 使用``*代表任意長 度的字串(這是另一種稱為 ``Pattern Matching Notation 的字串表示法).
Regular Expression 中則使用`` . 來代表``一個任意字元(注 意: 並非任意長度的字串). 而 Regular Expression 中`` *另有 其它涵意, 並不代表任意長度的字串. 例如
Regexp `` . 可用以代表任意一個字元. 如 ``A、``1、``+、...
Regexp `` ... 則代表一個由任意3個字元所的字串. 譬如 ``123、``abc、``# 1、...
[ \] 將特殊字元還原成字面意義的字元.
Regular Expression 中 特殊字元 將被解釋成特定的意義. 若要表示特殊字元的字面(literal meaning) 意義時, 在 特殊字元之前加上 ``\ 即可.
[例如 :] 使用 Regular Expression 來表示字串``a.out時, 不可寫成 Regexp `` a.out. 因為`` .在 Regular Expression 中是特殊字元, 表示任一字元.
可合乎(match) Regexp `` a.out 的字串將不只 ``a.out 一個; 字串``a2out,``a3out, ``aaout... 都合於 Regexp `` a.out.
正確的表示法應為 : Regexp `` a\.out
其他常用符號:
^ 限制字串必須出現於行首
$ 限制字串必須出現於行末
. 可代表任意字元
* 代表前一個符號代表的字符的任意長度
[xyz]一個字元他可以是x,y,z
[^xyz]一個字元他不可以是x,y,z
Regular Expression 的表示字串的內容主要可以分成兩大類:
Characters:一般字元(文數字元),所代表的意義與原字面的意義相同。
Operators:特殊字元(非文數字字元),代表某種特殊規則的意義。若要取消其代表意義,必須使用「\」跳脫字元。
例如:
"foo" 的 RE 表示字串 "foo" 的意思。
"[Ff]oo" 的 RE 表示字串 "Foo" 或字串 "foo" 的意思。
"F*"的 RE 表示F這個字元會出現0次或多次。
"F\*"的 RE 表示字串 "F*"的意思。
範例:
# 每行開頭第一個單字為「m」的行
[lcc09@localhost ~]$ egrep "^m" /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
mtchang:x:500:500::/home/mtchang:/bin/bash
# 每行結尾為「bash」的行
[lcc09@localhost ~]$ egrep "bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
mtchang:x:500:500::/home/mtchang:/bin/bash
lcc09:x:501:100::/home/lcc09:/bin/bash
身份證字號判斷

內容
S123456789 e123456789 D23456789 R223456789 F523456789
規則
執行過程
擷取mac-address範例

練習範例:底下為從hp2626 switch show mac-address 指令所取出的資訊,請使用RE規則找出網卡(mac)卡號.
請使用 http://osteele.com/tools/rework/ 此網頁提供的驗證功能試驗.
請使用 grep 配合 cut 指令輸出 mac 列表(有其它的解法??)
[root@station20 test]# vim mac.txt

 Status and Counters - Port Address Table

   MAC Address   Located on Port
  ------------- ---------------
  0002b3-4b38d2 1
  000496-27b85b 1
  000e7f-4030c1 1
  000ea6-6b7062 1
  000ea6-b4842b 1
  0010dc-8dbeed 7
  0010dc-8dbf03 7
  00110a-b96044 3
  001185-c0b543 1
  0018f3-1b84b3 5
  0018f3-636110 1
  001d60-842ab4 1
  001e8c-c82718 1
  001e8c-c82744 1
  001e8c-c82789 1
  001f29-71ba2e 1
  001f29-71ba2f 1
  001fc6-eb27d6 1
  00e02b-000001 1

cc#
osteele rework 的試驗解答
[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]
-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]
命令列的解法
egrep "[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]
-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]"
mac.txt | cut -f3 -d' '
更精簡的方式
osteele rework 的試驗解答
[0-9a-f]{6}-[0-9a-f]{6}
命令列 egrtep + cut
[root@]# egrep "[0-9a-f]{6}-[0-9a-f]{6}" mac.txt  | cut -d' ' -f3
0002b3-4b38d2
000496-27b85b
000e7f-4030c1
000ea6-6b7062
000ea6-b4842b
0010dc-8dbeed
0010dc-8dbf03
00110a-b96044
001185-c0b543
0018f3-1b84b3
0018f3-636110
001d60-842ab4
001e8c-c82718
001e8c-c82744
001e8c-c82789
001f29-71ba2e
001f29-71ba2f
001fc6-eb27d6
00e02b-000001
命令列 egrep + sed
[root@station20 test]# egrep "[0-9a-f]{6}-[0-9a-f]{6}" mac.txt  | sed 's/[0-9]$//g'
  0002b3-4b38d2
  000496-27b85b
  000e7f-4030c1
  000ea6-6b7062
  000ea6-b4842b
  0010dc-8dbeed
  0010dc-8dbf03
  00110a-b96044
  001185-c0b543
  0018f3-1b84b3
  0018f3-636110
  001d60-842ab4
  001e8c-c82718
  001e8c-c82744
  001e8c-c82789
  001f29-71ba2e
  001f29-71ba2f
  001fc6-eb27d6
  00e02b-000001
判斷 IP 是否正確

在一篇含有很多 ip address 的文章中,找出出現的 ip address
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 123.193.212.113
→ banqhsia:頭推                                                   06/27 21:47
→ banqhsia:0800-158-158  查ID專線                                 06/27 21:48
→ mp607:上面那個哪裡的電話?XD                                     06/27 21:49
→ nadoka:mini查IP專線  (無誤                                個鬼  06/27 21:50
※ 編輯: nadoka          來自: 123.193.212.113      (06/27 21:51)
推 banqhsia:查ID、查IP通用喔  ((將錯就錯XD                         06/27 21:52
規則
實做過程
擷取 email 範例

http://google.com 請上搜尋 'email gov.tw'
範例連結:全國ejob
使用正規表示式找出符合 email 特徵的例子.
簡單 email 判斷範例-規則
實做過程
RFC 關於 email address :Mail::RFC822::Address: regexp-based address validation
字串的修改: sed

Sed(Stream EDitor) 指令:
Sed(Stream EDitor)為 UNIX 系統上提供將編輯工作自動化的編輯器 , 使用者無需直接編輯資料。
Sed 可以分析 STDIN 的資料, 然後將資料經過處理後,再將他輸出到 STDOUT 的程式
sed語法編輯指令的格式:
[mtchang@cccm ~]$ sed --help
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...
當編輯指令在命令列上執行時 , 其前必須加上選項 -e 。其命令格式如下 :
  sed -e '編輯指令1'...  文件檔 
sed 編輯指令的格式如下 :
[address1[,address2]]function[argument]
位址參數 address1 、address2 為行數或 regular expression 字串 , 表示所執行編輯的資料行;函數參數 function[argument] 為 sed 的內定函數 , 表示執行的編輯動作。
位址參數表示法只是將要編輯的資料行 , 用它們的行數或其中的字串來代替表示它們。下面舉幾個例子說明(指令都以函數參數 d 為例) :
刪除檔內第 10 行資料 , 則指令為 10d。
刪除含有 "man" 字串的資料行時 , 則指令為 /man/d。
刪除檔內第 10 行到第 200 行資料, 則指令為 10,200d。
刪除檔內第 10 行到含 "man" 字串的資料行 , 則指令為 10,/man/d。
sed 的函數(function)
function 有底下這些選項:
a   :新增
c   :取代(行取代)
d   :刪除
i   :插入
p   :列印
s   :取代(字串取代)
function 詳細請見
SED手冊-chapter4
替換

範例:更換字串
將/etc/passwd檔案資訊中,其中第1行到第5行中的 bash 字串更換為 sh,並且將輸出結果加上行號,只顯示前10行以便觀看。
[root@server1 tmp]# head /etc/passwd | nl | sed -e '1,5s/bash/sh/'
     1  root:x:0:0:root:/root:/bin/sh
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6  sync:x:5:0:sync:/sbin:/bin/sync
     7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     8  halt:x:7:0:halt:/sbin:/sbin/halt
     9  mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10  news:x:9:13:news:/etc/news:
更換字串配合 pipe 使用 send
[root@server1 ~]# echo 'i love linux' | sed -e 's/love/shit/'
i shit linux
安靜模式

範例:只將第1行到第5行列出,-e 和 -n 出來的結果不一樣,原因如下:
n:使用安靜(silent)模式。
在一般 sed 的用法中,所有來自 STDIN的資料一般都會被列出到螢幕上。
但如果加上 -n 參數後,則只有經過 sed 特殊處理的那一行(或者動作)才會被列出來。
[mtchang@cccm ~]$ sed -e '1,5p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
.....(很多..略...)

# 加上 -n 參數後
[mtchang@cccm ~]$ sed -n '1,5p' /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
增加

範例:增加資料
在第一行加入 20071229 (今天的日期)字串
[root@server1 tmp]# head /etc/passwd | nl | sed -e "1a $(date +%Y%m%d)"
     1  root:x:0:0:root:/root:/bin/bash
20091211
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6  sync:x:5:0:sync:/sbin:/bin/sync
     7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     8  halt:x:7:0:halt:/sbin:/sbin/halt
     9  mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10  news:x:9:13:news:/etc/news:
刪除

範例:刪除第一行到第五行
[mtchang@cccm ~]$ sed -e '1,5d' /etc/passwd | head
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
替換行

範例:將第2行到第10行移除並取代為 「replace 2,10 line」字串
[mtchang@cccm ~]$ sed -e '2,10c replace 2,10 line' /etc/passwd | head
root:x:0:0:root:/root:/bin/bash
replace 2,10 line
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
rpm:x:37:37::/var/lib/rpm:/sbin/nologin

參考資料:SED手冊-中央研究院計算中心
sed指令練習

sed指令練習
請將 /var/log , /etc , /var/named, /home 其中 / 更換為 _ (底線)
請配合上一個章節的for 的語法文字串方式使用迴圈 for 處理
結果需為:
_var_log
_etc
_var_named
_home









練習過程1:有替換成功但不完全
[student@server1 ~]$ echo '/var/log' | sed -e 's/\//_/'
_var/log
練習過程2:請查看手冊關於s的細項參數
關於"s/pattern/replacement/[flag]"
* pattern : 它為 reguler expression 字串。它表示文件中要被替換的字串。
* replacement : 它為一般字串。但其內出現下列字元有特別意義 :
* flag : 主要用它來控制一些替換情況 :
o 當 flag 為 g 時 , 代表替換所有符合(match)的字串 。
o 當 flag 為十進位數字 m 時 , 代表替換行內第 m 個符合的字串。
o 當 flag 為 p 時 , 代表替換第一個符合 pattern 的字串後 ,
將資料輸出標準輸出檔。
o 當 flag 為 w wfile 時 , 代表替換第一個符合 pattern 的字串後 , 輸出到
 wfile 檔內(如果 wfile 不存在 , 則會重新開啟名為 wfile 的檔案)。
o 當沒有 flag 時 , 則將資料行內第一個符合 pattern 的字串以 replacement
 字串來替換 。
練習過程3:套用迴圈
[student@server1 ~]$ more for.sh
#!/bin/bash
for NAME in /var/log /etc /var/named /home
do
    echo $NAME
done
[student@server1 ~]$ ./for.sh
/var/log
/etc
/var/named
/home
練習過程4:完整解答
[student@server1 ~]$ more for.sh
#!/bin/bash
for NAME in /var/log /etc /var/named /home
do
    echo $NAME | sed -e 's/\//_/g'
done
[student@server1 ~]$ ./for.sh
_var_log
_etc
_var_named
_home
參考資料

參考資料:
一個可以即時驗證及產生程式語法的正規表示式驗證網頁
Email的RFC 2822規範
中研院Regular Expression簡介
http://irw.ncit.edu.tw/peterju/webslide/re/
http://saturn.stu.edu.tw/~ckhung/b/re/
http://www.rtfiber.com.tw/~changyj/

沒有留言: