データベース入門 資料 2
ファイル・ディレクトリ操作とシェルの特殊文字

今野 英明

平成26年4月21日


?

1 ディレクトリとパス名

この章の内容に関するより詳しい説明は,例えば, 昨年度の情報機器の操作テキスト 「ディレクトリ」や「パス名」の資料にあります。

1.1 コマンドに対するファイル/ディレクトリ名の指定方法

  1. カレントディレクトリ内のファイルやディレクトリを扱う場合

    ファイル名やディレクトリ名のみ1 を記述すればよい。

  2. カレントディレクトリ以外のファイルやディレクトリを扱う場合

    パス名を記述する。

1.2 パス名

パス名は,ディレクトリ/ファイルの階層構造内の位置情報を含んだ,ファイルやディレクトリの名前である。
  1. 絶対パス名

    ルートディレクトリを基点として,ディレクトリやファイルの位置を表すもの。

    1. ルートディレクトリは /
    2. ルートディレクトリ以外のディレクトリやファイルについては,最初の / でルートディレクトリを表し,それ以降,子ディレクトリ(サブディレクトリ) を / で区切って記述する。 この / はディレクトリやファイルの親子関係を表す区切り記号である。

    例)

  2. 相対パス名

    カレントディレクトリとの相対的な関係によって,ディレクトリやファイルの位置を表もの。 相対パスでは,カレントディレクトリを . (ドット) で表し,親ディレクトリを .. (ドット二つ)で表す。 絶対パスとの表記上の大きな違いは,パス名の先頭に / を付けないこと。

    例)

1.3 練習問題

\includegraphics{pathname_ex_fig.eps}

  1. 前回の練習問題で作成したディレクトリ db14 をカレントディレクトとしましょう。

  2. ディレクトリ db14 に temp というディレクトリを作り,正しく作成できたことを確認しましょう。

  3. 今作成した temp をカレントディレクトリとしましょう。 この操作が成功したかどうか確認しましょう。

  4. echo コマンドとリダイレクトを使って,ディレクトリ temp に junk という名前のファイルを作りましょう。 junk の中身は waste という単語とします。 作成したら中身を確認しましょう。

  5. ファイル junk を,カレントディレクトリ (temp) の親ディレクトリである db14 に一度のコマンド操作で移動しましょう。

    移動するファイル junk はカレントディレクトリ内のファイルですから,ファイル名で指定すればいいですが,移動先は親ディレクトリなのでディレクトリ名での指定はできません。

  6. 親ディレクトリである db14 をカレントディレクトリとしましょう。 操作が終わったら,うまくいったか確認しましょう。

  7. ディレクトリ temp を削除しましょう。

  8. ディレクトリ /pub/db_a に存在するファイル theDarkSideOfTheMoon の中身を閲覧(表示)しましょう。 ファイル名をすべてタイプする代わりにタブキーによる補完機能を使うこと。

  9. ファイル theDarkSideOfTheMoon をディレクトリ db14 に複写しましょう。

  10. 9 で複写したファイルの中身に Floyd という語を追加してください。

2 コマンド行における特殊文字の扱い

コマンドを入力する行(コマンド行)の内容を解釈して,コマンドを実行するのはシェルという種類のプログラムでした。 ここでは,コマンドに引数を与えて実行する際に必要となる,シェルにとって特別な意味のある文字の取り扱いを学びます。 また,検索等で必要となる,文字列のマッチングに関する考え方の基礎を習得します。


2.1 メタキャラクタ

カレントディレクトリに,仮に a1,a2, ...,a5 という 5 つの通常のファイルと distdir というディレクトリのみが存在するとし,a1,..., a5 を distdir に移動したいとします。 ファイル移動のコマンドは mv であり,mv の引数には複数のファイルを指定できますから,
mv a1 a2 a3 a4 a5 distdir
を実行すれば希望は叶えられますが,移動するファイルをすべて列挙するのは面倒です。

この例のように,一度のコマンド操作で複数のファイルを処理したいとき,メタキャラクタ(meta-character)という,シェルにとって特殊な意味のある文字を利用すると便利です。 メタキャラクタを用いると,上記の操作は

mv a? distdir
mv a* distdir
で済みます。a? と a* は,シェルによって共に a1 a2 a3 a4 a5 に展開 (置き換え) されてから,引数として mv コマンドに渡されます。

2.1.1 ? と *

? と * は,一言でいえば,
? : 任意の1文字
* : 任意の文字列
にマッチする2メタキャラクタです。 その具体的な使い方を次の例で見てみます。

  1. 準備
    1. カレントディレクトリを /pub/db_a/metawork に変更してください。 うまくいったかどうか,pwd コマンドで確認してください。

    2. ls コマンドを使ってカレントディレクトリに存在するファイルを確認してください。 次のファイルがあります。
      A A1 B C a a1 a11 a12 a13 a2 a3 b b1 b11

  2. ? の使い方

    echo コマンドは,引数に与えた文字列をそのまま表示するコマンドでした。 例えば,

    echo abc d e
    を実行すると,画面に abc d e と表示されます。 この echo コマンドを使い,? を含む引数がどのようなファイル名に展開されるのかを調べましょう。
    1. 次のコマンドを順番に実行してください。
      echo ?
      echo ??
      echo ???
      echo ????
      echo の引数に ? を与えても,? とは表示されません。

      シェルは ? をカレントディレクトリに存在する 1 文字からなるファイル名のリストに展開し,引数として echo コマンドに渡します。 その結果として 1 文字からなるファイル名がすべて表示されます。

      同様に,?? は 2 文字の,??? は 3 文字のファイル名に展開されます。 4 文字のファイル名をもつファイルはカレントディレクトリに存在しないので,最後の例では,その旨のメッセージが出ます。

    2. ? を他の文字と組み合わせて使うこともできます。
      echo a?
      echo ?1?
      最初の例では,ファイル名の先頭が a であって,その後に何という文字でも構わないから,1文字が続くものに展開されます。 その次の例は,1 の前後に任意の 1 文字が存在するファイル名に展開されます。

    3. ? はパス名の一部として使うことができます。 例えば,
      echo /bin/????
      だと,/bin というディレクトリに存在するファイルのうち,4 文字のファイル名をもつものが該当します。

      なお,? はファイル名の先頭にある . や,パス名の区切り記号 / にはマッチしません。

  3. * の使い方

    * は ? に似ていますが,1 文字のみではなく,任意の長さの文字列にマッチする点が異なります。

    次の例は,各々 a と a1 で始まるファイル名に展開されます。

    echo a*
    echo a1*
    最初の例で注意すべきは,展開されたファイル名の中に a が含まれていることです。 すなわち,任意の長さには,0 文字の長さも含みます。 同じ理由から,2 番目の例でも,a1 が結果に含まれます。

    次の結果も,容易に予想できるでしょう。

    echo *3
    echo *
    echo /bin/*

    なお,? の場合と同様に,* はファイル名の先頭にある . や,パス名の区切り記号 / にはマッチしませんので,これらは明示的に記述する必要があります。 例えば,カレントディレクトリに存在する . で始まるファイル名をすべて扱うには .* とする必要があります。

以上,? や * がどのようなファイル名に展開されるのかを調べるために echo コマンドのみを使ってきましたが,メタキャラクタはシェルが解釈する特殊文字なので,コマンドの引数一般に利用することができます3

例えば,カレントディレクトリに存在する a で始まるファイルを調べたければ,ls a* を実行するのが自然でしょう。 なお,ls の引数にファイル名を与えると,そのファイルの情報のみが表示されます。

2.1.2 その他のメタキャラクタ

ファイル名やディレクトリ名に展開される,*? 以外のメタキャラクタとして,次のものもあります。
~ ホームディレクトリ (csh 系のシェルで利用可能)
[c1c2...] [ ] 内の1文字([c1-c2]を用いて文字範 囲を指定することも可能)
{string1,string2, ...} { } 内の文字列
これらは次のように使います。
echo ~ 
ls ~ 
echo ~/a* 
echo [abc]
ls [abc]
echo [A-Z]*
echo /{bin,usr,var}
ls /{bin,usr,var}
[abc] は a, b, c のいずれかのファイル名に,[A-Z]* は大文字で始まるファイル名に展開されます。 /{bin,usr,var}/bin /usr /var に展開されます。

2.2 特殊文字の無効化

echo コマンドを使って,画面に What is your name? と表示するにはどうすればいいでしょう。
echo What is your name?
を,結果を予想してから実行してみましょう。

メタキャラクタである ? を,普通の文字として echo コマンドで出力するには,シェルによる ? の展開を抑止(エスケープ)してから,echo コマンドの引数に与える必要があります。

また,シェルが特殊な意味を持つ記号として解釈する文字には,$",空白等,これまでに紹介した以外にも存在します。 コマンド行において,それらを普通の文字として扱う場合にも,次のようにして特殊文字の持つ意味を無効にする必要があります。

  1. 単一の特殊文字 c に対する特殊な意味の無効化
    \c

  2. 文字列 string 内の特殊文字に対する特殊な意味の無効化
    'string'

2.2.1 例

echo What is your name\?
echo 'What is your name?'
前者の場合,echo の引数が 4 個であるのに対し,後者では一つです。

時間に余裕があれば, tcsh のオンラインマニュアルを読むことも有意義です。

2.3 練習

  1. カレントディレクトリを,ホームディレクトリ内の db14 に変更した上で, ディレクトリ /pub/db_a/metawork に存在する b で始まる名前のファイルを,一度の操作で全てカレントディレクトリに複写してください。

  2. echo コマンドを使って画面に What's your name? と表示する方法を考え,いろいろと試してみてください。

  3. cp a b ccp 'a b' c は,各々,何をするための操作かを考えてください。

    これらを実際に行うために必要なファイル等を,echo コマンド等で作成してから,実際に操作を試してください。

    (ヒント:ファイル名には空白文字を含めることも可能です。ただし,この問を解く以外の場面では推奨しません。)



...ファイル名やディレクトリ名のみ1
これらは相対パス名でもあるので,ファイル名やディレクトリ名の指定は,カレントディレクトリにあるファイル/ディレクトリであるか否かに拘らず,パス名で記述すればよいと考えてもよい。
... にマッチする2
後に説明しますが,? と * ともに,ファイル名先頭の . (ドット) や / にはマッチしません。
... コマンドのみを使ってきましたが,メタキャラクタはシェルが解釈する特殊文字なので,コマンドの引数一般に利用することができます3
Windows では * や ? はワイルドカードと呼ばれます。 Windows では,スタートボタンからコマンドプロンプトを起動すれば,キーボードからのコマンド入力が可能であり,そこでワイルドカードを利用できます。 ただし,コマンドプロンプトでのワイルドカードは,シェルではなく,各コマンドが解釈するものなので,ワイルドカードが利用できるかどうかは実行するコマンドに依存します。