Linux - bash でテキストファイルから行抽出!

Updated:


Linux(Unix 含む) であるテキストファイルの中から、条件に合致する行だけを出力する bash スクリプトについてです。

結構使うので記録しておきます。

作業メモ

0. 前提条件

  • Cygwin 1.7.15 での作業を想定していますが、Linux, BSD でも同様です。
  • 使用するシェルは bash です。

1. テキストファイルの準備

今回のテストでは以下のようなテキストファイルを使用する。 (固定長のテキストファイルです)

【ファイル名: test.txt】

1002 (株)あいうえお      MO    100        459 [13]            ( 1 )
1004 (株)かきくけこ      MO      1     96,600 [13]            ( 1 )
1034 (株)さしすせそ      JS    100        486 [13]            ( 1 )
1054 (株)たちつてと      JS      1     28,870 [13]      [15]  ( 2 )
1085 (株)なにぬねの      N2    100      1,758 [13] [14]       ( 2 )
1093 はひふへほ(株)      JS      1    106,000      [14]       ( 1 )
1094 まみむめも(株)      Ce      1    247,000 [13]            ( 1 )
1090 やゆよ(株)        T1    100      3,675 [13] [14] [15]  ( 3 )
1094 らりるれろ(株)      T1    100      1,507      [14]       ( 1 )
1066 (株)わをん        JS    100         66 [13]            ( 1 )

2. bash スクリプトの作成

たとえば、上記のテキストファイルの中で、各行末が “( 2 )” か “( 3 )” で終わる行だけをそのまま抽出したい場合の例です。 判定部分に正規表現を使用しています。

【ファイル名:test.sh】

#!/bin/sh
# ファイル名設定
FILE_NAME="test.txt"

# IFS は文字列リストのフィールド区切り文字で、デフォルトは半角スペース。
# 行をそのまま取り込むために IFS を改行に変更
OLDIFS="$IFS"
IFS="\n"

# 1行ずつ処理
while read LINE
do
    # 行末が "( 2 )" or "( 3 )" の行だけ出力
    if [[ "$LINE" =~ \(\ [23]\ \)$ ]]; then
        echo $LINE
    fi
done < $FILE_NAME

# IFS を元に戻す
IFS="$OLDIFS"

【注意】 IFS (= Internal Field Separator : 内部フィールド区切り文字) という特殊変数にはデフォルトで「半角スペース」が設定されています。 設定を変更せずにこのまま使用すると、取得した行内の複数の半角スペースが 1 個に圧縮されたようになってしまいます。 事前に IFS に「改行」を設定し、処理終了後に元に戻すようにしています。

また、判定部分の正規表現はダブルクォーテーションで囲まない、半角スペースは “\s” ではなく “\ “ を使用しないといけいないようです。 正規表現の詳細については、別途各自お調べください。

3. bash スクリプトの実行

以下のようにして bash スクリプトを実行する。 今回は分かりやすくする為、使用するテキストファイルと bash スクリプトは同じディレクトリに配置している。

$ ./test.sh
1054 (株)たちつてと      JS      1     28,870 [13]      [15]  ( 2 )
1085 (株)なにぬねの      N2    100      1,758 [13] [14]       ( 2 )
1090 やゆよ(株)        T1    100      3,675 [13] [14] [15]  ( 3 )

判定部分は、正規表現を色々弄ればどうにでもなります。 当方、Cygwin でも Linux でも意外とよく使うので、今回記録しておいた次第です。

以上。





 

Sponsored Link

 

Comments