[Litz' UNION] > [Dal Segno] > [UNIXたん] > [その6] // [その5][その7]

UNIXたん その6

フィルタ

フィルタとは、入力したテキストに加工を施して出力するプログラムを指します。
簡単な機能を持つフィルタをパイプで繋げることによって、複雑な大量のテキストを容易に加工することができます。

基本的なフィルタプログラムを以下に紹介します。がんがん使いましょう。

cat

前述。

フィルタとしては「何も加工せず、そのまま出力する」ものです。以下補足

ファイル名を与えないと、標準入力を読み込んで出力します。
-n オプションを付けると、行番号を表示します。
-b オプションを付けると、行番号を表示します(空行をカウントしない)。
-s オプションを付けると、連続する空行を1つにまとめます。
-v オプションを付けると、コントロールコードを文字で表示します。

tee

前述。

grep

指定したパターンにマッチする行を出力します。無害

grep pattern file とすると、fileから文字列「pattern」を含む行を検索して出力します。
パターンには正規表現を使うことができますが、その時はパターンを引用府で囲むこと。

ファイル名を複数与えることもできます。ワイルドカード展開もしてくれます。
ファイル名を与えないと、標準入力から検索して表示します。
-#(数字) オプションを付けると、マッチした行の前後#行も表示します。
-A #(数字) オプションを付けると、マッチした行の後#行も表示します。
-B #(数字) オプションを付けると、マッチした行の前#行も表示します。
-c オプションを付けると、マッチした回数を表示します。
-e pattern オプションを付けると、patternが検索パターンであることを明示します。
(複数個のパターンを指定する時に使います。)
-E オプションを付けると、拡張正規表現を使います。( egrep と同じ)
-F オプションを付けると、パターンを単なる文字列として検索します。( fgrep と同じ)
-i オプションを付けると、大文字小文字を区別しません。
-n オプションを付けると、マッチした行の行番号を表示します。
-v オプションを付けると、パターンにマッチしない行を表示します。
-Z オプションを付けると、圧縮されたファイルからgrepします。( zgrep と同じ)

egrep

指定したパターンにマッチする行を表示します。無害

基本的には grep と同じようなもの。 grep -E と等価。
パターンには拡張正規表現が使われます。

fgrep

指定したパターンにマッチする行を表示します。無害

基本的には grep と同じようなもの。 grep -F と等価。
指定したパターンを単なる文字列として扱います。正規表現は無効。

zgrep

指定したパターンにマッチする行を表示します。無害

基本的には grep と同じようなもの。 grep -Z と等価。
compress, gzip で圧縮したファイルをgrepします。

ps から、emacs の情報のみを抽出したい場合

> ps -axu | grep emacs
litz 390 0.0 0.3 9712 1912 p2 S 8:11AM 0:00.05 emacs
litz 392 0.0 0.0 1416 308 std S+ 8:11AM 0:00.00 grep emacs


grep emacs 自身も出てくるのが嫌なら、さらに工夫して

> ps -axu | grep '[0-9] emacs'
litz 390 0.0 0.3 9712 1912 p2 S 8:11AM 0:00.05 emacs

sort

与えられた行を順番に並べ直します。無害

sort file とすると、fileの各行を(デフォルトでは文字列として)ソートして出力します。
ファイル名を与えないと、標準入力から読み込んでソートします。

-f オプションを付けると、大文字小文字を区別しません。
-m オプションを付けると、それぞれが既にソートされている複数のファイルをソートする時、動作が若干速くなります。
-r オプションを付けると、逆順にソートします。
-n オプションを付けると、数字としてソートします。
-u オプションを付けると、同一内容の行を一つにまとめます。
+#(#は数字) オプションを付けると、指定した数のフィールドに従ってソートします。

文字列としてソート
> sort <<EOF
2
10
5
EOF

10
2
5


数字としてソート
> sort -n <<EOF
2
10
5
EOF

2
5
10


ファイルリストをサイズ順にソート
> ls -al | sort -n +4
total 232
-rw-r--r-- 1 litz staff 0 Jun 5 18:37 a
-rw-r--r-- 1 litz staff 0 Jun 5 18:37 b
-rw-r--r-- 1 litz staff 18 Jun 6 00:00 aaa
drwxr-xr-x 2 litz staff 68 Jun 5 20:10 unix5
(以下略)

左から4つ目(0番目が左端であることに注意)の要素 0, 0, 18, 68…でソートします。

uniq

連続する同一内容の行を一つにまとめます。無害

uniq file とすると、fileの隣り合う同じ行を1行にまとめて出力します。
ファイル名を与えないと、標準入力から読み込んで実行します。

-c オプションを付けると、同じ行が連続した回数も表示します。
-d オプションを付けると、連続する同じ行のみを表示します。

> sort -c <<EOF
A
A
B
A
EOF

2 A
1 B
1 A


"A"が2行連続、"B"が1行、"A"が1行。

tr

入力されたテキストの置換を行います。無害

tr 古い文字集合 新しい文字集合 < file とすると、file内で置換を行います。
文字列単位でなく、文字単位での置換を行う点に注意。
また、それぞれの文字数は揃えること(異なっていても動作する)。
tr -d 古い文字集合 < file とすると、文字を削除します。

ファイル名を与えないと、標準入力から読み込んで置換・削除を行います。

eをEに置換
> tr e E <<EOF
test
EOF

tEst

小文字を大文字に、大文字を小文字に
> tr a-zA-Z A-Za-z <<EOF
testTEST
EOF

TESTtest

数字を削除
> tr -d 0-9 <<EOF
a1b2c3
EOF

abc

head

ファイルの先頭部分を出力します。無害

head file とすると、fileの先頭10行を出力します。
ファイル名を与えないと、標準入力から読み込んで実行します。

-#(#は数字) オプションを付けると、先頭#行を表示します。
-n #(#は数字) オプションを付けると、先頭#行を表示します(上に同じ)。
-c #(#は数字) オプションを付けると、先頭#バイトを表示します。

tail

ファイルの最終部分を出力します。無害

tail file とすると、fileの末尾10行を出力します。
ファイル名を与えないと、標準入力から読み込んで実行します。

-#(#は数字) オプションを付けると、末尾#行を表示します。
-n #(#は数字) オプションを付けると、末尾#行を表示します(上に同じ)。
-c #(#は数字) オプションを付けると、末尾#バイトを表示します。

fold

テキストを一定幅に整形して出力します。無害

fold fileとすると、fileの各行を80文字(デフォルト)で折り返して行分割して出力します。
ファイル名を与えないと、標準入力から読み込んで実行します。

-w #(#は数字) オプションを付けると、#行で折り返します。

> fold -w 3 <<EOF
sample
EOF

sam
ple

expand

入力されたテキストのタブをスペースに変換します。無害

expand file とすると、fileのタブをスペースに変換して出力します。

unexpand

入力されたテキストのスペースをタブに変換します。無害

unexpand file とすると、fileのスペースをタブに変換して出力します。

pr

入力されたテキストにタイムスタンプをつけます。無害

pr file とすると、fileが印刷するのにイイ感じになって出力されます。

wc

前述。

nkf

前述。

compress

ファイルを圧縮します。ほぼ無害

compress file とすると、fileが圧縮されます。
圧縮後のファイル名は、圧縮前のファイルに拡張子「.Z」を付けたものです。

-c オプションを付けると、圧縮結果を標準出力に書き出します。ファイル操作はしません。
-f オプションを付けると、圧縮後の方が却ってサイズが大きくなる場合でも躊躇しません。
-v オプションを付けると、圧縮率を出力します。

uncompress

compress形式の圧縮ファイルを伸長します。ほぼ無害

uncompress file とすると、fileが伸長されます。
伸長後のファイル名は、伸長前のファイルから拡張子「.Z」を除いたものです。

-c オプションを付けると、伸長結果を標準出力に書き出します。ファイル操作はしません。
-f オプションを付けると、伸長後のファイルと同名のファイルがあっても躊躇しません。
-v オプションを付けると、圧縮率を出力します。

zcat

compress形式の圧縮ファイルの中身を表示します。無害

zcat file とすると、圧縮ファイルの中身を閲覧することができます。
compress形式だけでなく、gzip形式のファイルの内容を表示できることもあります。

gzip

ファイルを圧縮します(高機能)。ほぼ無害

gzip file とすると、fileが圧縮されます。
圧縮後のファイル名は、圧縮前のファイルに拡張子「.gz」を付けたものです。

-c オプションを付けると、圧縮結果を標準出力に書き出します。ファイル操作はしません。
-d オプションを付けると、ファイルを伸長します(gunzip と等価)。

gunzip

gzip形式の圧縮ファイルを伸長します。ほぼ無害

gunzip file とすると、fileが伸長されます。gzip -d と等価。
伸長後のファイル名は、伸長前のファイルから拡張子「.gz」を除いたものです。

-c オプションを付けると、伸長結果を標準出力に書き出します。ファイル操作はしません。

gzcat

gzip形式の圧縮ファイルの中身を表示します。無害

gzcat file とすると、圧縮ファイルの中身を閲覧することができます。gzip -dc と等価。
gzip形式だけでなく、compress形式のファイルの内容を表示できます。

tar

前述。

cut

テキストを切り出して出力します。無害

cut -c#(#は数字) とすると、#文字目を切り出します。

cut -c5 … 5文字目を切り出す。
cut -c5 … 5文字目から行末までを切り出す。
cut -c-5 … 行頭から5文字目を切り出す。
cut -c5-10 … 5文字目から10文字目を切り出す。
cut -c5,10 … 5文字目と10文字目を切り出す。

cut -b#(#は数字) とすると、#バイト目を切り出します。
cut -f#(#は数字) とすると、#フィールド目を切り出します。デフォルトの区切りはタブ。
cut --d 文字 -f#(#は数字) とすると、指定した文字で区切り、#フィールド目を切り出します。

正規表現

正規表現とは、文字列の集合を表すルールのことです。
「〜で始まって〜で終わる文字列」などといったものを指定するのに正規表現は使われます。
以下に文法と例を示します。

^ … 行頭
$ … 行末
. … 任意の1文字
[文字群] … 文字群の中のどれか1文字。-(ハイフン) を用いた範囲指定も可能
[^文字群] … 文字群に含まれない1文字
* … 直前のパターンの0回以上の繰り返し
+ … 直前のパターンの1回以上の繰り返し
? … 直前のパターンの0or1回の出現
{数字} … 直前のパターンの指定回数の繰り返し
{数字1,数字2} … 直前のパターンの(1)回以上(2)回以下の繰り返し。どちらか片方のみの指定でも良い
(パターン) … 囲んだパターンをグループ化する
\数字 … グループ化されたパターンで(数字)番目のもの
| … 直前および直後のパターンのどちらか

tion$ … 「tion」で終わる行にマッチ。
^[0-9] … 数字で始まる行にマッチ。
あた{5,} … 文字列「あたたたたた…」(「た」が5回以上現れる)にマッチ。
([0-9]{2})-\1 … 12-12, 09-09 などにマッチ。
re(fl)|(dir)ection … reflection, redirection にマッチ。

プログラマブルフィルタ

単機能フィルタだけでは難しい複雑な処理を行うには、シェルスクリプトを組むか、通常言語でのプログラムを組むことになります。
しかし、シェルスクリプトは制限が多いし、通常言語でフィルタを組むのは無駄が多い。それは面倒だ、と。
そこでプログラマブルフィルタの出番。無駄なく柔軟にフィルタが組めます。

プログラマブルフィルタとしてはsedの他にもawk, perl, rubyなどがありますが、これらはプログラミング言語と捉えた方が良いので、まずはsedのみ解説していきます。

sed

文字列の変換をします。無害

sed -e 'スクリプト' とすると、sedのスクリプトを実行して出力します。
sed -f スクリプトファイル名 とすると、ファイルからスクリプトを読み込んで実行し、出力します。

-n オプションを付けると、pコマンドによる出力命令がなければ出力しません。

sedのスクリプトの書き方

処理対象となる行の指定 {
 コマンド
 コマンド
}

基本的に、これを書き連ねていく。
コマンドは3行以上になっても良いし、1行でも良い(この場合は{}は不要)。
また、対象行を指定しない場合はコマンドのみ書く。

行の指定方法

・行番号で指定(5行目なら「5」と書く)
・正規表現を含む行(「/正規表現/」と書く)
・最終行のみ指定(「$」と書く)

以上の3通り。
2つの行指定を「,」で繋いで書くと、範囲指定になる。
※「/sample/,20」 … 「sample」の含まれる行から20行目まで

コマンドの書き方

s/正規表現/マッチした箇所に置換える文字列/フラグ … 文字列を置換する
置換え文字列には、& というメタ文字も使える。マッチした部分、の意
フラグは、g(全て置換する)、 n(数字。n番目にマッチした文字列を置換する)、p(置換が行われたら表示する)の3種類。

p … その行を表示する
d … その行を削除する
q … sed自体を終了させる

2つ目のeをaに変える
> sed -e 's/e/a/2' <<EOF
tee
EOF

tea

-n オプションをつけてみる
> sed -ne 's/e/a/2' <<EOF
tee
EOF

(出力は無し)

pコマンドを入れてみる
> sed -ne 's/e/a/2; p' <<EOF
tee
EOF

tea

カレントディレクトリのファイル *.text を全て *.txt に変換する
> ls *.text | sed -ne 's/\(.*\).text$/mv & \1.txt/gp' | tcsh

[Litz' UNION] > [Dal Segno] > [UNIXたん] > [その6] // [その5][その7]