3.2 レッスン 1
Certificate: |
Linux Essentials |
---|---|
Version: |
1.6 |
Topic: |
3 コマンドラインの力 |
Objective: |
3.2 ファイルからデータを検索して取得する |
Lesson: |
1 of 2 |
はじめに
このレッスンでは、あるソースから別のものに情報を送信ないし転送することに焦点を当てます。 Linuxコマンドラインでは、標準的なチャネルを介して情報を転送します。コマンドの標準入力( stdin またはチャネル0)はキーボードに、標準出力( stdout またはチャネル1)は画面に相当します。コマンドやプログラムのエラーメッセージを転送する、エラー出力( stderr またはチャネル2)というチャンネルもあります。入力や出力は、リダイレクトする(向け直す)ことができます。
コマンドを実行するときに、指定の情報をコマンドに引き渡したり、出力をファイルにリダイレクトしたいことがあります。 これらの機能について、次の2つのセクションで説明します。
I/Oリダイレクト
I/Oリダイレクトを用いると、テキストファイルを使用して、コマンドがやりとりする情報を向け直す(リダイレクトする)ことができます。前述のように、標準入力、標準出力、エラー出力を切り替えて、テキストファイルから情報を取得できます。
標準出力のリダイレクト
標準出力を画面ではなくファイルにリダイレクトするには、 >
オペレーターの後にファイル名を指定します。ファイルが存在しない場合は新しいファイルが作成されますが、存在する場合は出力によって既存のファイルが上書きされます。
作成したファイルの内容を確認するには、cat
コマンドを使用します。このコマンドは、デフォルトではファイルの内容を画面に表示します。機能の詳細については、マニュアルページを参照してください。
以下の例は、オペレーターの機能を示しています。最初の例では、 “Hello World!” というテキストを含む、新しいファイルが作成されます。
$ echo "Hello World!" > text $ cat text Hello World!
2回目の呼び出しでは、同じファイルが新しいテキストで上書きされます。
$ echo "Hello!" > text $ cat text Hello!
ファイルの最後に新しい情報を追加したい場合は、>>
オペレーターを使用します。 このオペレーターも、既存のファイルが見つからない場合には新しいファイルを作成します。
最初の例は、テキストの追加を示します。新しいテキストが最後の行に追加されました:
$ echo "Hello to you too!" >> text $ cat text Hello! Hello to you too!
次の例は、新しいファイルの作成を示します:
$ echo "Hello to you too!" >> text2 $ cat text2 Hello to you too!
標準エラーのリダイレクト
エラーメッセージだけをリダイレクトするには、2>
オペレーターの後にエラーを書き込むファイル名を指定します。 ファイルが無い場合は新しいファイルが作成され、既存の場合はファイルが上書きされます。
説明したように、標準エラーをリダイレクトするには チャネル2 を使います。標準出力の チャンネル1 はデフォルトなので省略できますが、標準エラーをリダイレクトする場合にはチャンネルを指定しなくてはなりません。たとえば、次のコマンドは、 games
という名前のファイルまたはディレクトリを検索し、標準出力を画面に表示しながら、エラーのみを text-error
ファイルに書き込みます。
$ find /usr games 2> text-error /usr /usr/share /usr/share/misc ---------出力省略---------- /usr/lib/libmagic.so.1.0.0 /usr/lib/libdns.so.81 /usr/games $ cat text-error find: `games': No such file or directory
Note
|
|
例えば、次のコマンドではエラーが起きないため、text-error
ファイルには何の情報も書き込まれません。
$ sort /etc/passwd 2> text-error $ cat text-error
標準出力と同様に、2>>
オペレーターを使って、標準エラーをファイルに追加できます。 つまり、ファイルの末尾に新しいエラーが追加されます。 ファイルが存在しない場合は、新しいファイルが作成されます。 1つ目の例では新しい情報をファイルに追加していますが、2番目の例では同じ名前のファイルが見つからないので、新しいファイルを作成しています。
$ sort /etc 2>> text-error $ cat text-error sort: read failed: /etc: Is a directory
$ sort /etc/shadow 2>> text-error2 $ cat text-error2 sort: open failed: /etc/shadow: Permission denied
このリダイレクトでは、エラーメッセージだけがファイルにリダイレクトされ、通常の出力は標準出力(stdout)を経由して画面に表示されます。
ビットバケツ(bit bucket: 入力を受け入れるが何もしないファイル)という特別なファイルがあります: /dev/null
です。次の例に示すように、表示したくない、あるいはファイルにリダイレクトしたくない、無関係な情報のリダイレクト先として使用します。(訳注: 日本ではビットバケツという呼び方はあまり一般的ではありません。そのままデブヌルと呼ぶ人が多いようです。)
$ sort /etc 2> /dev/null
標準入力のリダイレクト
キーボードではなく指定されたファイルからコマンドにデータを入力するために使用するリダイレクトもあります。このリダイレクトには、例に示すように <
オペレーターを使用します。
$ cat < text Hello! Hello to you too!
標準入力のリダイレクトは、引数にファイルを受け付けないコマンドで主に使用されます。tr
コマンドはその1つです。このコマンドでは、特定の文字を削除するなど、一連の文字を指定した方法で処理して、ファイルの内容を変更します。以下の例では、文字 l
を削除します。
$ tr -d "l" < text Heo! Heo to you too!
詳細は tr
のmanページを参照をしてください。
ヒアドキュメント
<<
オペレーターは、出力リダイレクトなど他のオペレーターとは異なる働きをします。これは ヒアドキュメント (here document)と呼ばれて、コマンドや対話型プログラムに宛てて、テキストやコードブロックをリダイレクトするために使用します。bash
、sh
、csh
などと同様のスクリプト言語に対して、ファイルを使わずに、直接コマンドラインから入力を与えることができます。
以下の例に示しますが、このオペレーターはコマンドに入力データを与えるために使用しますが、オペレーターの後に指定する単語はファイル名ではありません。単語は入力の区切りと解釈されて、入力には含まれませんから、cat
では表示されません。
$ cat << hello > hey > ola > hello hey ola
詳細な情報は、cat
コマンドのmanページを参照してください。
組み合わせ
標準出力と標準エラー出力を組み合わせて、同じファイルにリダイレクトすることから始めましょう。 &>
と &>>
オペレーターを使用しますが、ここでの &
は チャンネル1 と チャンネル2 を組み合わせることを示しています。1つ目のオペレーターは既存の内容を上書きし、2つ目のオペレーターはファイルの末尾に新しい情報を追加します。どちらのオペレーターも、説明済みのオペレーターと同様に、ファイルが存在しない場合には新しいファイルを作成します。
$ find /usr admin &> newfile $ cat newfile /usr /usr/share /usr/share/misc ---------出力省略---------- /usr/lib/libmagic.so.1.0.0 /usr/lib/libdns.so.81 /usr/games find: `admin': No such file or directory $ find /etc/calendar &>> newfile $ cat newfile /usr /usr/share /usr/share/misc ---------出力省略---------- /usr/lib/libmagic.so.1.0.0 /usr/lib/libdns.so.81 /usr/games find: `admin': No such file or directory /etc/calendar /etc/calendar/default
cut
コマンドの使用例を見てみましょう:
$ cut -f 3 -d "/" newfile $ cat newfile share share share ---------Omitted output---------- lib games find: `admin': No such file or directory calendar calendar find: `admin': No such file or directory
cut
コマンドは、入力ファイルから -f
オプションで指定されたフィールドを切り出します。上の例では3番目のフィールドです。コマンドがフィールドを見つけられるように、-d
オプションで区切り文字を指定する必要があります。上の例では、文字 /
が区切りになります。
cut
コマンドについての詳細は、manページを参照してください。
コマンドのパイプ
リダイレクトは、主にコマンドの結果を格納し、別のコマンドで処理するために使用します。データを何段階も処理する場合、この種の中間処理は面倒で複雑なものになりがちです。これを避けるために、コマンドを直接リンクする、パイプ(pipe)を使うことができます。すなわち、最初のコマンドの出力が、自動的に2番目のコマンドの入力になります。このリンクには、|
(縦棒)オペレーターを使います。
$ cat /etc/passwd | less root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh :
上の例では、パイプオペレーターの後の less
コマンドでファイルの表示方法を変更しています。less
コマンドはテキストファイルを(ページ単位で)表示したり、1行ずつ上下にスクロールしたりすることができるもので、前のレッスンで学んだように、manページの表示にもデフォルトで使われています。
同時に複数のパイプを使用することもできます。入力を受け取って変更して出力するる中間コマンドを、フィルター と呼びます。ls -l
コマンドを使って、出力の最初の10行から単語数を数えてみましょう。デフォルトではファイルの最初の10行を表示する head
コマンドを使用し、次に単語数を数える wc
コマンドを使用します。
$ ls -l | head | wc -w 10
説明したように、デフォルトで head
は、指定されたテキストファイルの最初の10行だけを表示します。この動作は、オプションを使用することで変更することができます。 詳細はコマンドのmanページを参照してください。
ファイルの末尾を表示する tail
というコマンドもあります。デフォルトでは、このコマンドは最後の10行を選択して表示しますが、head
と同様に行数を変更することができます。tail
のmanページを参照してください。
Note
|
|
wc
(word count)コマンドは、デフォルトでファイルの行数、単語数、バイト数を数えます。演習で示しますが、-w
オプションを指定すると、コマンドは単語数のみを数えます。このコマンドでよく使用されるオプションは、行数を数える -l
と、バイトを数える -c
です。wc
コマンドのさまざまなオプションと詳細については、コマンドのmanページを参照してください。
演習
-
現在のディレクトリの内容を、所有権とパーミッションを含めてリスト表示し、ホームディレクトリ内の
contents.txt
というファイルにリダイレクトして出力しましょう。 -
現在のディレクトリにある
contents.txt
ファイルの内容をソートして、contents-sorted.txt
というファイルの末尾に追加しましょう。 -
/etc/passwd
ファイルの末尾10行を出力し、自分のDocuments
ディレクトリ内の新しいファイルにリダイレクトしましょう。 -
contents.txt
ファイル内の単語数を数えて出力し、ホームディレクトリ内のfield2.txt
ファイルの末尾に追加しましょう。入力と出力の両方のリダイレクトを使用してください。 -
/etc/passwd
ファイルの先頭5行を出力し、アルファベットの逆順に並べ替えましょう。 -
先に作成した
contents.txt
ファイルから、最後の9行の文字数を数えてみましょう。 -
/usr/share
ディレクトリとそのサブディレクトリから、test
というファイルの数を数えてみましょう。 ヒント:find
コマンドから出力される各行が、ファイルを表します。
発展演習
-
contents.txt
ファイルの2番目のフィールドを選択して、標準出力とエラー出力の両方をfield1.txt
ファイルにリダイレクトしましょう。 -
入力リダイレクトオペレーターと
tr
コマンドを使用して、contents.txt
ファイルからダッシュ(-
)を削除しましょう。 -
エラーのみをファイルにリダイレクトする最大の利点は何でしょうか?
-
contents.txt
ファイルをアルファベット順に並び替えて、連続するスペースを1つのスペースに置き換えましょう。 -
1行のコマンドで、(前問で行ったように)連続するスペースを1つにまとめ、9番目のフィールドを選択し、それを大文字/小文字を区別しないアルファベットの逆順でソートしましょう。いくつのパイプが必要でしょうか?
まとめ
このレッスンでは、次のことを学びました。
-
リダイレクトの種類
-
リダイレクトオペレーターの使い方
-
コマンド出力をフィルターするパイプの使い方
このレッスンで使用したコマンド:
cut
-
ファイルの各行からセクション(フィールド)を取り除きます。
cat
-
ファイルを表示したり、結合します。
find
-
ディレクトリ階層からファイルを探します。
less
-
ファイルを表示し、1行ずつスクロールできます。
more
-
ファイルをページ単位で表示します。
head
-
ファイルの先頭10行を表示します。
tail
-
ファイルの末尾10行を表示します。
sort
-
ファイルをソートします。
wc
-
デフォルトでは、ファイル内の行、単語、バイトの数を表示します。
演習の解答
-
現在のディレクトリの内容を、所有権とパーミッションを含めてリスト表示し、ホームディレクトリ内の
contents.txt
というファイルにリダイレクトして出力しましょう。$ ls -l > contents.txt
-
現在のディレクトリにある
contents.txt
ファイルの内容をソートして、contents-sorted.txt
というファイルの末尾に追加しましょう。$ sort contents.txt >> contents-sorted.txt
-
/etc/passwd
ファイルの末尾10行を出力し、自分のDocuments
ディレクトリ内の新しいファイルにリダイレクトしましょう。$ tail /etc/passwd > Documents/newfile
-
contents.txt
ファイル内の単語数を数えて出力し、ホームディレクトリ内のfield2.txt
ファイルの末尾に追加しましょう。入力と出力の両方のリダイレクトを使用します。$ wc < contents.txt >> field2.txt
-
/etc/passwd
ファイルの先頭5行を出力し、アルファベットの逆順に並べ替えましょう。$ head -n 5 /etc/passwd | sort -r
-
先に作成した
contents.txt
ファイルから、最後の9行の文字数を数えてみましょう。$ tail -n 9 contents.txt | wc -c 531
-
/usr/share
ディレクトリとそのサブディレクトリから、test
というファイルの数を数えてみましょう。 ヒント:find
コマンドから出力される各行が、ファイルを表します。$ find /usr/share -name test | wc -l 125
発展演習の解答
-
contents.txt
ファイルの2番目のフィールドを選択して、標準出力とエラー出力の両方をfield1.txt
ファイルにリダイレクトしましょう。$ cut -f 2 -d " " contents.txt &> field1.txt
-
入力リダイレクトオペレーターと
tr
コマンドを使用して、contents.txt
ファイルからダッシュ(-
)を削除しましょう。$ tr -d "-" < contents.txt
-
エラーのみをファイルにリダイレクトする最大の利点は何でしょうか?
エラーのみをファイルにリダイレクトすることは、監視が必要なログの保持に役立ちます。
-
contents.txt
ファイルをアルファベット順に並び替えて、連続するスペースを1つのスペースに置き換えましょう。$ sort contents.txt | tr -s " "
-
1行のコマンドで、(前問で行ったように)連続するスペースを1つにまとめ、9番目のフィールドを選択し、それを大文字/小文字を区別しないアルファベットの逆順でソートしましょう。いくつのパイプが必要でしょうか?
$ cat contents.txt | tr -s " " | cut -f 9 -d " " | sort -fr
この演習では、フィルター毎に1つで、3つのパイプを使っています。