grep (regex)

最後更新: 2019-05-15

目錄

  • 一個要小心的錯誤
  • skip 某 Folder
  • 好用的 -w (whole words)
  • Disable regex
  • 只找某格式的檔案
  • grep 的 return
  • 數有幾多行
  • Line-Number
  • 開頭與結尾(^, $)
  • NOT OR AND
  • 彩色
  • egrep, fgrep
  • 面對 Binary 檔
  • Regular Expressions
  • grep in ps without grep
  • Context Line Control
  • Line buffered
  • 其他常用參數
  • Tips

 


一個要小心的錯誤

 

grep -v "#" /etc/vsftpd.conf > /etc/vsftpd.conf

它會清空 vsftpd.conf .............

 


skip 某 Folder

 

# --exclude-dir=GLOB

 * When searching recursively, skip any subdirectory whose base name matches GLOB

cd wordpress

grep -rni --exclude-dir wp-admin 'function ' wordpress

 


好用的 -w (whole words)

 

grep -w user /etc/passwd

# 當有 user, user1, user2 存在時, 只有 user 會中

# 會中的有效字 letters, digits, and the underscore

# 不過當 grep -w "test.123" file 時, 它會中 "testx123"

 


Disable regex

 

-F, --fixed-strings                      # Interpret PATTERN as a list of fixed strings

Matcher Selection

  • -F, --fixed-strings
  • -E, --extended-regexp     # Default
  • -P, --perl-regexp

 


只找某格式的檔案

 

[方案1] --include

grep -rl --include=*.txt YOUR_STRING .

[方案2] 配合 find

find . -name "*.php" -exec grep -rl YOUR_STRING '{}' \;

 


grep 的 return

 

  • normally: 0
  • found: 1
  • error: 2

 


數有幾多行

 

cat file.txt | grep something |wc -l

何不:

grep -c something file.txt

 


Line-Number

 

-n, --line-number

 

 


開頭與結尾(^, $)

 

grep ^apple test.txt

grep apple$ test.txt

 


NOT OR AND

 

not:

grep -v "#" /etc/vsftpd.conf

or:

grep [ae] test.txt

grep -e apple -e banana test.txt

grep "app\|pear" test.txt

egrep 'app|pear' test.txt

and:

無次序:

grep apple test.txt | grep pear

有次序:

egrep apple.*pear test.txt

 


彩色

 

--color

 


egrep, fgrep

 

  • egrep    --> grep -E
  • fgrep    --> grep -F

 


面對 Binary 檔

 

-a, --text

Process a binary file as if it were text;

this is equivalent to the --binary-files=text option.

沒有加 "-a" 時

grep CONFIG_LOG_BUF_SHIFT /boot/config-*

Binary file /boot/config-3.10.0-1160.31.1.el7.x86_64 matches

 


Regular Expressions

 

  • BRE(basic-regexp): 沒有 ?, +, {, |,  (,  and  )
  • ERE (extended-regexp) (-E, --extended-regexp)
  • Perl regular expression(-P, --perl-regexp)

P.S.

很多時它們會配合 "-o, --only-matching" 使用

-o    # Print only the matched (non-empty) parts of a matching line,

           with each such part on a separate output line.

i.e. 只要 mail ID

mailq

-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
11A60E0398    92617 Fri Sep 10 15:41:53  [email protected]
...

mailq | grep -oE [A-Z0-9]{10}

11A60E0398

Basic 可用的如下: (-G, --basic-regexp -e,  --regexp)

  • .                       # any single character, except a newline
  • *                      # zero or more
  • [^...]                # not
  • [0-9]                # [[:digit:]]
  • [a-z]                 # [[:lower:]]
  • [A-Z]                # [[:upper:]]
  • [A-Za-z]            # [[:alpha:]]
  • [0-9A-Za-z]       # [[:alnum:]]  <-- \w is a synonym for [_[:alnum:]] ( \W= [^_[:alnum:]] )
  • ' '                      # [[:space:]]
  • [ \t]                  # [[:blank:]]
  • [A-Fa-f0-9]        # [[:xdigit:]]
  • ^, $                  # 頭, 尾
  • \< and \>          # respectively match the empty string at the beginning and end of a word.

應用

在 maillog 找 from 某人時

# 不可以 "from=<*@remote.domain>", 因為 * 是形容前置字符數量

grep "from=<.*@remote.domain>" /var/log/maillog

from=<x@mydomain> to=<[email protected]>

解決

grep "from=<[[:alnum:]]*@remote.domain\>" /var/log/maillog

OR

grep "from=<[0-9A-Za-z]*@remote.domain\>" /var/log/maillog

簡寫

    grep "from=<\w*@remote.domain\>" /var/log/maillog

Extended (-E, --extended-regexp)

  • ?             # zero or one
  • +            # one or more
  • {n,m}     # minimum n and the maximum m
  • |             # or
  • (, )          # 對應 $1, $2

group

(?:) 名叫 Non capturing group

SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

依上例, 它是沒有 Group1 的

\<(.+?)\> [^<]*? \</\1\>

 


grep in ps without grep

 

ps aux | grep perl | grep -v grep

OR

ps aux | grep [p]erl

 


Show line After/Before hit keyword

 

-B NUM, --before-context=NUM

Print NUM lines of trailing context after matching lines.

-A NUM, --after-context=NUM

Print NUM lines of trailing context after matching lines.

-C NUM, -NUM, --context=NUM

Print NUM lines of output context.

Example

grep -A 2 'keyword' /path/to/file

grep -B 2 'keyword' /path/to/file

docker info | grep 'Storage Driver' -A 4
 Storage Driver: aufs
  Root Dir: /volume1/@docker/aufs
  Backing Filesystem: extfs
  Dirs: 14
  Dirperm1 Supported: true

 

 


Line buffered

 

--line-buffered

Use line buffering on output. This can cause a performance penalty.

 


其他常用參數

 

  • -i            # 不分大小寫
  • -r           # 整個目錄及其下所有層
  • -x           # 中一整行
  • -L           # show files-without-match
  • -l            # input file
  • -h, --no-filename                         # Suppress the prefixing of file names on output.
  • -m NUM, --max-count=NUM         # Stop reading a file after NUM matching lines

 

 


Tips

 

[1] 找出特定檔案有某字串

[錯誤] cat */.sieve | grep yahoo

[正確] grep -l yahoo */.sieve

 

 

 

Creative Commons license icon Creative Commons license icon