\documentstyle[epsf,ascmac,alltt,fancybox]{jarticle}
\title{ワイルドカードとコマンド}
\date{}
\author{}
\newcommand{\dg}{\gt}
\newcommand{\dm}{\min}
\setlength{\topmargin}{-12mm}
\setlength{\textheight}{24.5truecm}
\setlength{\textwidth}{17truecm}
\setlength{\oddsidemargin}{-8.5mm}
\setlength{\evensidemargin}{-8.5mm}
\newcommand{\丸数字}[1]
{{\ooalign{\hfill\(\scriptstyle#1\)\hfill\crcr\(\bigcirc\)}}}
\newcommand{\CR}{\ovalbox{\ooalign{\hfill\(\scriptstyle\hookleftarrow\)
\hfill\crcr}}}
\begin{document}
\maketitle
ワイルドカード (wild card) とは，元もとトランプのカードの中で，
何のカードにも変わるカード ({\bf joker} など) を示す言葉で，UNIX では，
どのような文字 (文字列) にもマッチする文字を指す．
以下のワイルドカードがある．
\begin{center}\begin{tabular}{c|l}
\hline
{\tt *} & どのような文字列にもマッチする．\\
\hline
{\tt ?} & どのような文字にもマッチする．\\
\hline
\end{tabular}\end{center}
{\tt *} や {\tt ?} を，アルファベットや数字などと混ぜて使うことができる．
例えば，以下の表の通りである．
\begin{center}\begin{tabular}{c|l}
\hline
{\tt ?bcd?fg} & {\tt abcdefg}，{\tt 1bcdefg} は OK．
{\tt acdefg}，{\tt 1bcdfd} は NG \\
\hline
{\tt ?est.*} & {\tt test.txt}，{\tt test.k} は OK. 
{\tt est.tex}，{\tt test.} は NG \\
\hline
\end{tabular}\end{center}

ここで，{\tt *}，{\tt ?} は，何もない文字(列) にはマッチしないこと
({\tt ?est} に対して，{\tt est} など) にはマッチしないことに注意しよう．

ワイルドカードは，多くの場合，ファイル名の指定のときにつかう．
大きく分けて，2 通りが考えられるがいくつかのコマンドを使って説明しよう．
\begin{itemize}
\item コマンドライン\footnote{プロンプトの次にあるカーソルから，
コマンドを入力するときの，コマンドから \CR キーまでの一行を指す．}
でコマンドの引数の一部で使う．
\item ファイル名をしている文字列の中で使う({\tt find} コマンドなど)．
\end{itemize}

\section{コマンドラインで使う}
前回説明した簡単なコマンドでも，通常のコマンド入力において，引数として
ファイル名を指定するときには，ワイルドカードを使うことができる．
これは，後述する {\dg\bf シェル}(shell)
がワイルドカードをカレントディレクトリの
ファイル名またはディレクトリ名に変換するためである．

例えば，現在のカレントディレクトリがホームディレクトリで，以下の
ファイルまたは，ディレクトリがあると仮定しよう．
\begin{itembox}[l]{ホームディレクトリ}
\begin{alltt}
prompt\% \underline{ls}\CR
GNUstep/         Xrootenv.0       embed_pcf.ps.gz  seminar/
Mail/            backup.txt       nsmail/          test.txt
\end{alltt}
\end{itembox}
このホームディレクトリをカレントディレクトリとすると，
{\tt echo} コマンドをワイルドカードを用いて使う．
\begin{itembox}[l]{{\tt echo} コマンドとワイルドカード(1)}
\begin{alltt}
prompt\% \underline{echo *}\CR
GNUstep Mail Xrootenv.0 backup.txt embed_pcf.ps.gz nsmail seminar test.txt
\end{alltt}\end{itembox}
このように，カレントディレクトリにあるファイル名，ディレクトリ名が
表示される．つまり，ワイルドカード {\tt *}(アスタリスク) が
カレントディレクトリのファイル名または，ディレクトリ名にマッチし，
表示されたことがわかる(ただし，ディレクトリ，ファイルの区別は
されないことに注意しよう)．

ワイルドカードは，他のアルファベットなどと組み合わせて使うことができる．
\begin{itembox}[l]{{\tt echo} コマンドとワイルドカード(2)}
\begin{alltt}
prompt\% \underline{echo *.txt}\CR
backup.txt test.txt
prompt\% \underline{ls *.txt}\CR
backup.txt  test.txt
\end{alltt}
\end{itembox}
ファイル名の{\dg\bf 拡張子}(extension) が揃ったファイル(この場合は，
{\tt .txt} となる)のみを対象としたいときには，便利な機能である．

\section{文字列検索コマンド}
複数のファイルに共通にある{\dg\bf 文字}(character)，{\dg\bf 文字列}
(character string) を一度に検索したい場合に文字列検索コマンドを
使う．{\tt egrep}，{\tt grep}，{\tt fgrep} がある．
これら 3 つのコマンドは使い方は同じであるので，{\tt man} コマンドを
使うと同じコマンドとして扱われていることがわかる．

元もと，{\tt grep} コマンドが開発され，後に検索効率のよいコマンドとして
{\tt egrep}，{\tt fgrep} が開発された．さらに最近は，
それらを {\tt grep} というコマンドで統一しているので
「使い方」も実体もほぼ同じであると考えてよい
({\tt egrep} は，{\tt grep -E} と同じ．マニュアル参照)．

\begin{itembox}[l]{文字列検索コマンドの使い方}
\begin{alltt}
egrep "検索文字列" ファイル名
\end{alltt}
\end{itembox}
検索文字列の中が，アルファベットや数字など (記号以外) のみのときは，
{\dg\bf ダブルクオテーション}(double quotation) を省略することが
できる．

\begin{itembox}[l]{文字列検索コマンド(1)}
\begin{alltt}
prompt\% \underline{egrep this *.txt}\CR
/home/yas/test.txt:this pen is blue.
/home/yas/backup.txt:this is a pen.
prompt\% \underline{egrep test /etc/rc.d/init.d/*}\CR
/etc/rc.d/init.d/apmd:  test -r "$CONFIG" && . "$CONFIG"
/etc/rc.d/init.d/atd:test -x /usr/sbin/atd || exit 0
/etc/rc.d/init.d/nvi-m17n.recover:      # Only test files that are readable.
/etc/rc.d/init.d/nvi-m17n.recover:      if test ! -r $i; then
/etc/rc.d/init.d/nvi-m17n.recover:      if test -x $i -o ! -s $i; then
/etc/rc.d/init.d/nvi-m17n.recover:      # Only test files that are readable.
/etc/rc.d/init.d/nvi-m17n.recover:      if test ! -r $i; then
/etc/rc.d/init.d/nvi-m17n.recover:      if test -n "$recfile" -a -s "$recfile"; then
\end{alltt}
\end{itembox}
文字列検索コマンドで，ファイル名を指定する部分は，ワイルドカードを使って
複数のファイルを指定する場合が多い．
{\tt n} オプションにより，ファイルでの行番号を表示することができる．
\begin{itembox}[l]{文字列検索コマンド(2)}
\begin{alltt}
prompt\% \underline{egrep -n test /etc/rc.d/init.d/*}\CR
/etc/rc.d/init.d/apmd:18:       test -r "$CONFIG" && . "$CONFIG"
/etc/rc.d/init.d/atd:16:test -x /usr/sbin/atd || exit 0
/etc/rc.d/init.d/nvi-m17n.recover:23:   # Only test files that are readable.
/etc/rc.d/init.d/nvi-m17n.recover:24:   if test ! -r $i; then
/etc/rc.d/init.d/nvi-m17n.recover:30:   if test -x $i -o ! -s $i; then
/etc/rc.d/init.d/nvi-m17n.recover:41:   # Only test files that are readable.
/etc/rc.d/init.d/nvi-m17n.recover:42:   if test ! -r $i; then
/etc/rc.d/init.d/nvi-m17n.recover:50:   if test -n "$recfile" -a -s "$recfile"; then
\end{alltt}
\end{itembox}
各ファイル名の後に表示される数字が，行番号である．

正確には，検索文字列としてワイルドカードを拡張したような
パターンを表現する {\dg\bf 正規表現}(regular expression)
を指定することができるが，ここでは説明しない．

\section{{\tt find} コマンド}
ファイル名または，ディレクトリ名を検索するのが {\tt find} コマンドである．
\begin{itembox}[l]{{\tt find} コマンドの使い方}
\begin{alltt}
find 開始ディレクトリ -name "検索名" -print
\end{alltt}
\end{itembox}
{\dg\bf 開始ディレクトリ}(start directory) とは，
検索を開始するディレクトリで，このディレクトリの
下にあるファイルまたは，ディレクトリをすべて検索する．
通常，カレントディレクトリ({\tt .}) か，比較的上層のディレクトリを
指定し，広範囲に検索する．
{\dg\bf 検索名} には，ワイルドカードを使うことができる．
{\tt find} コマンドには，他のオプションもあるので，マニュアルを参照しよう．
\begin{itembox}[l]{{\tt find} コマンド}
\begin{alltt}
prompt\% \underline{cd}\CR
prompt\% \underline{find . -name "test*" -print}\CR
./test.txt
./test.txt~
prompt\% \underline{find . -name "ls*" -print}\CR
/usr/bin/lsdic
/usr/bin/lsattr
/usr/bin/lsdev
find: /usr/doc/procps-1.2.9_jp: Permission denied\ \ \ \ \ \(\leftarrow\)読み出し許可がない．
find: /usr/doc/trr-1.0: Permission denied\ \ \ \ \ \(\leftarrow\)読み出し許可がない．
/usr/lib/mc/extfs/lslR
/usr/lib/tclX8.0.3/help/tcl/lists/lsearch
/usr/lib/tclX8.0.3/help/tcl/lists/lsort
/usr/local/latex2html/styles/lsorbian.perl
/usr/man/man1/ls.1
/usr/man/man1/lsattr.1
/usr/man/man1/lsmod.1
/usr/man/man2/lseek.2
/usr/man/man2/lstat.2
/usr/man/man3/lsearch.3
\(<略>\)
\end{alltt}
\end{itembox}

2 番目の例では，{\tt /usr} ディレクトリ以下，{\tt ls} で始まる
ファイルまたは，ディレクトリを検索している．

{\tt Permission denied} と表示されるディレクトリは，
読み出し許可がないディレクトリで，検索することができないディレクトリを指す．

\section{{\tt sed} コマンド}
{\tt sed} コマンドは，文書整形コマンド(text formatter)または，
ストリームエディタ(stream editor) といい，テキストファイルを読み込んで
その内容を編集する機能がある．
基本的には，文字列検索コマンド {\tt grep} を拡張して作られたコマンド
で以下のような形式で使う．
\begin{itembox}[l]{{\tt sed} コマンド}
\begin{alltt}
sed '編集コマンド' 入力ファイル名 > 出力ファイル名
\end{alltt}
\end{itembox}
{\tt sed} コマンドだけではファイルを整形し，表示(標準出力に出力) する
のみであるので，リダイレクションにより，結果を出力するファイルを指定する．
編集コマンドは例えば，以下のように指定する．
\begin{center}\begin{tabular}{c|c|l}
\hline
オプション & 編集コマンド & 機能 \\
\hline
なし & {\tt s/taro/hanako/g} & 
	ファイル中の {\tt taro} を {\tt hanako} に変更する．\\
\hline
なし & {\tt /test/d} & {\tt test} を含む行を削除する．\\
\hline
{\tt -n} & {\tt /\verb:^:d/p} & 先頭に {\tt d} がついた行のみ表示する．\\
\hline
\end{tabular}\end{center}
編集コマンドには，{\tt ed} というエディタのコマンドを書き，
正規表現を駆使してファイルを編集する．
正規表現については説明しないので，上のコマンドについてのみ理解すればよい．

\begin{itembox}[l]{文字列を置き換える}
\begin{alltt}
prompt\% \underline{ls -l | sed 's/yas/taro/g'}\CR
total 122
drwxrwxr-x   5 taro      taro          1024 Apr 10 14:52 GNUstep/
drwxr-xr-x  20 taro      taro          1024 May 19 17:50 Mail/
-rw-rw-r--   1 taro      taro           592 May 20 10:31 Xrootenv.0
-rw-rw-r--   1 taro      taro            62 May 20 00:59 backup.txt
-rw-rw-r--   1 taro      taro        113459 May  1 07:15 embed_pcf.ps.gz
drwx------   2 taro      taro          1024 Apr 10 15:40 nsmail/
drwxrwxr-x   7 taro      taro          1024 May 18 22:32 seminar/
-rw-rw-r--   1 taro      taro            36 May 20 00:59 test.txt
\end{alltt}
\end{itembox}
{\tt ls} コマンドからパイプで受渡された情報の中で，
文字列 {\tt yas} を {\tt taro} に置き換えている．

\begin{itembox}[l]{行を削除する}
\begin{alltt}
prompt\% \underline{ls -l | sed '/\/$/d'}\CR
total 122
-rw-rw-r--   1 yas      yas           592 May 20 10:31 Xrootenv.0
-rw-rw-r--   1 yas      yas            62 May 20 00:59 backup.txt
-rw-rw-r--   1 yas      yas        113459 May  1 07:15 embed_pcf.ps.gz
-rw-rw-r--   1 yas      yas            36 May 20 00:59 test.txt
\end{alltt}\end{itembox}
{\tt ls} コマンドからパイプで受渡された情報の中で，
文字 {\tt /} を最後に含む行を削除する．
つまり，「ファイル」のみを表示する．

\begin{itembox}[l]{指定した行のみ表示}
\begin{alltt}
prompt\% \underline{ls -l | sed -n '/^d/p'}\CR
drwxrwxr-x   5 yas      yas          1024 Apr 10 14:52 GNUstep/
drwxr-xr-x  20 yas      yas          1024 May 19 17:50 Mail/
drwx------   2 yas      yas          1024 Apr 10 15:40 nsmail/
drwxrwxr-x   7 yas      yas          1024 May 18 22:32 seminar/
\end{alltt}
\end{itembox}
{\tt ls} コマンドからパイプで受渡された情報の中で，
先頭に {\tt d} がある行のみを表示する．
つまり，「ディレクトリ」のみを表示する．
\end{document}


