« 2012年4月 | トップページ

2013年12月の1件の記事

2013年12月 5日 (木)

bashの正規表現その2(不完全版)

久しぶりのエントリです。bashスクリプトの正規表現・・・とかいうタイトルで5年前に書いたのですが、これは、bash自身というよりも、exprコマンドで正規表現が扱えますよ・・・という内容でした。まぁそれはそれで良いと思うのですが、実はbash自身に正規表現の機能があるってことを最近知ったので、書いてみます。

お題

データを行毎に記録したテキストファイル(例:data.txt)がある。そのテキストファイルを1行ずつ読み取って、コマンドを実行したい。ただし、#で始まる行や空行は無視したい。

入力

$ cat data.txt 
one 
#two
thr#ee
four 
  
five 
six# 
se #ven
 
 nine 
ten 
$

解答と実行結果

[[ 対象文字列 =~ 正規表現 ]]
でマッチ/アンマッチの判定ができる。ポイントは、正規表現をダブルクォートで囲まない事。みたい。
$ cat regexp.sh 
#!/bin/sh 
TARGET_FILE="data.txt" 
while read LINE 
do 
    if [[ $LINE =~ (^#|^ *$) ]]
    then 
        continue 
    else 
        echo "$LINE" 
    fi 
done < $TARGET_FILE
 
$ ./regexp.sh
one
thr#ee
four
five
six#
se #ven
nine
ten
$ 

後方参照

さらには、括弧でくくった場所を
${BASH_REMATCH[x]}
で後方参照できる。
${BASH_REMATCH[0]} #-> マッチ全体
${BASH_REMATCH[1]} #-> 1番目の括弧
${BASH_REMATCH[2]} #-> 2番目の括弧
:

お題2

#記号を含む行を出力したい。加えて、該当行のうち#記号から行末までの文字列を抜き出したい。

解答と実行結果

$ cat ./regexp2.sh
#!/bin/bash
TARGET_FILE="data.txt"
while read LINE
do
    if [[ $LINE =~ ^[^#]*(#.*)$ ]]
    then
        echo -n "${BASH_REMATCH[0]},"
        echo    "${BASH_REMATCH[1]}"
    else
        :
    fi
done < $TARGET_FILE
 
$ ./regexp2.sh
#two,#two
thr#ee,#ee
six#,#
se #ven,#ven
$

メタキャラクタ

良く分からないのは、このbashの正規表現で使えるメタキャラクタです。数値の意味で\dが使えないのです。(文字'd'にマッチしちゃうみたい)どこかにbashで使える正規表現のメタキャラクタの一覧がないかなぁ。

| | コメント (0) | トラックバック (0)

« 2012年4月 | トップページ