LoginSignup
69

More than 3 years have passed since last update.

正規表現 & sed & awk

Last updated at Posted at 2016-04-11
  • echo がエスケープ文字 (\n など) を解釈しない場合は -e オプションをつける

POSIX 正規表現

grep のパターン、および sed 's/A/B/'A (置換対象) などで使えるもの

名前 基本正規表現
(BRE)
拡張正規表現
(ERE)
対象文字列 (表現は ERE) 例 (ERE)
キャラクタリスト
Character list
[ ] (同じ) 囲まれた文字のどれか
- で連続した範囲を指定
^ はそれ以外とマッチ
[ABC]
[0-9]
[^0-9]
キャラクタクラス
Character class
[: :] (同じ) 特定の文字集合を表す [[:alpha:]]
[^[:digit:]]
照合シンボル
Collating symbol
[. .] (同じ) 複数文字を 1 文字として扱う [[.hoge.]]
等価クラス
Equivalence class
[= =] (同じ) 等価に扱う文字の集合を表す
[[=e=]]
[[=u=]]
ドット
Dot
. (同じ) 任意の 1 文字 .
エスケープ文字
Escaped
character
\x (同じ) メタ文字 x 自身 \.
先頭マッチ・
末尾マッチ
Anchoring
^
$
(同じ) 行の先頭 (^)・末尾 ($)
(先頭・末尾以外では通常文字となる)
^#
\.\$
繰返し指定子
Single-character
duplication
*


\{n\}
\{n,\}
\{n,m\}
*
+
?
{n}
{n,}
{n,m}
*{0,} と同じ
+{1,} と同じ
?{0,1} と同じ
{n} は直前の文字が n 文字連続
{n,}n 文字以上連続
{n,m}n 文字以上 m 文字以下連続
.*
a{3,5}
包括指定子・
後方参照子
Grouping
\( \)
\n
( )
\n
() でマッチの塊を扱う
\nn 番目の () に対応
([a-z]*) \1*
論理和指定子
Alternation
\|
(GNU 拡張)
| | の左または右の文字列 ^ABC|DEF\$

sed s/A/B/B (置換後の文字列) で使えるもの

名前 BRE / ERE 置換される文字列
後方参照子 \n n 番目の () でマッチした文字列 \1
全体マッチ & マッチした文字列全体 &
エスケープ文字 \x メタ文字 x 自身 \&

grep コマンド

使い方
$ grep [options] 'pattern' input_file
  • パターンは正規表現
    • デフォルトは基本正規表現 (BRE)、オプションで -E を指定すると拡張正規表現 (ERE)
    • メタ文字 (| など) を扱う場合はクオートで囲む
  • -i オプションは大文字・小文字の区別を無視する
  • -v オプションはマッチしなかった行を表示する

sed コマンド

使い方
$ sed [options] 'pattern[;pattern...]' input_file
  • パターンは " で囲むと特殊記号がシェルに展開されてしまうので、' で囲むようにする
  • sed: RE error: illegal byte sequence となったら $ export LANG=C でロケールを変更する
  • 正規表現はデフォルトで BRE、-E-r オプションで ERE
  • -n オプションがあると、修正された行だけを出力する

パターン pattern の前半部分 (処理する行の指定)

記法 処理される行
n n 行目
$ は最後の行を表す
1
n,m n 行目から m 行目
1,3
n~m n 行目から m 行ごと 3~2
(3, 5, 7, ...行目)
n,~m n 行目から次の m の倍数行まで 5,~4
(5 から 8 行目)
/regexp/
/regexp/!
/re1/,/re2/
正規表現 regexp とマッチする行
マッチしない行
re1 にマッチした行から re2 にマッチした行まで
/hoge/

パターン pattern の後半部分 (処理の指定)

記法 処理
= 行番号を前の行に表示
(-n オプションで行番号だけを抽出)
/dog/=
a word 文字列 word を次の行に追加 /dog/a hoge
i word 文字列 word を前の行に追加 1,2i hoge
q 処理をそこで終了する /dog/q
c word 選択された行を指定された文字列を置換
(word には\nを含んでよい)
/dog/c hoge
d 行を削除 2d
p 行を表示
(-nオプションで条件に合う行だけ抽出)
2p
s/regexp/replace/ 正規表現 regexp とマッチする文字列を replace に置換
デリミタは / 以外でもよい (例: |;)
デフォルトでは最初のマッチだけ処理
末尾に g があると全マッチを処理
s/N//g
y/target/replace/ target の各文字を replace の各文字に変換
(両者は同じ長さでなければならない)
y/acgt/ACGT/

gsed コマンド

  • (BSD の) sedでは置換のパターン中に含まれる (メタ文字以外の) エスケープ文字を正しく認識できないので、そのような場合は GNU 拡張の gsed を使う
    • $ echo -e "\t" | gsed 's/\t/OK/g'
    • ただし、改行については次のやり方でないとダメ
    • $ echo -e "\n" | gsed ':loop; N; $!b loop; ;s/\n/OK/g'
  • 他にも、-i(--in-place) オプションを使うことで、指定されたファイルを開いて置換して保存してくれる
    • $ gsed -i "s/hoge/huga/g" *.txt のような書き方が可能になる
    • BSD だと for でファイル名をそれぞれ展開して処理してからリダイレクトしないとダメ

awk コマンド

使い方
$ awk [option] 'pattern{action}[pattern{action}...]' input_file
  • sed と同様にプログラム (ルールの集合) は ' で囲むようにする

組み込み変数

組み込み変数名 説明 デフォルト値
RS レコード (読み込みの単位) セパレータ 改行
FS フィールド (レコードの要素の単位) セパレータ
-F オプションで変更可
スペース
NR 現在のレコード番号
NF 現在のレコードが持つフィールド数
$0 現在のレコード全体
$1, ..., $NF 現在のレコードの各フィールド (代入も可)

パターン pattern

pattern アクションが実行される条件 ルールの例
(パターンなし) 常に実行 {print \$NF}
BEGIN 先頭行を読み込む前に実行 BEGIN {print "Not Read"}
END 最終行の処理が終わった後に実行 END {print "Already Read"}
/regexpr/
expr ~ /regexpr/
expr !~ /regexpr/
レコード全体が regexpr にマッチしたら実行
exprregexpr にマッチしたら実行
exprregexpr にマッチしなければ実行
/hoge/ {print \$1}
\$1 ~ /^>/ {print \$0}
\$1 !~ /^>/ {print \$0}
cond 条件式 cond が真のとき実行 length(\$0) == 0 {print "Nothing"}

アクション action で使用可能な関数・構文の一例

action 説明
word1 word2 文字列・変数の連結
空白を挟むだけ
print word
printf word
文字列を表示
print は改行あり、printf は改行なし
printf(...) C の printf 関数と同じように使う
index(s,t) 文字列 s で文字列 t が現れる最初の位置を返す
length(s) s を文字列と見なしてその長さを返す
substr(s,b)
substr(s,b,l)
sb 番目の文字以降を返す
sb 番目から始まる長さ l の文字列を返す
tolower(s)
toupper(s)
s 中の大[小]文字を小[大]文字にした文字列を返す
gsub(regexpr,word,s) regexpr とマッチする s 中の文字列を word に置換
word& にするとマッチした文字列になる
s を省略すると \$0 に対して行われる
返り値はマッチした個数
for(...){...} C と同じか、for(i in array) のようにもできる
if(...){...} else{...} C と同じ方
(アクションなし) {print $0} と同じ挙動 (= 条件に合う行の抽出)

Steve Turner の bioinformatics におけるワンライナー集には sed, awk 以外にもいろいろなコマンドの例が載っている。

  • multi-fasta をそれぞれの fasta に分割
    • awk '/^>/{s=++d".fa"} {print > s}' multi.fa
  • fasta 中の各 sequence の名前とその長さを表示
    • awk 'BEGIN {c=-1;} $0 ~ ">" {if(c>=0){print c}; c=0; printf substr($0,2,100) "\t";} $0 !~ ">" {c+=length($0);} END {print c;}' file.fa
  • fastq を fasta に変換
    • sed -n '1~4s/^@/>/p; 2~4p' file.fq > file.fa
  • 指定された範囲の行を表示
    • awk 'NR>=20&&NR<=80' input.txt
  • 指定された列に操作を施して最後の列に追加
    • awk '{print $0,$2+$3}' input.txt
  • fastq 中の read の平均長を求める
    • awk 'NR%4==2{sum+=length(\$0)}END{print sum/(NR/4)}' file.fq

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
69