今回は簡単なテキスト処理を行います。いつも長いので今回は短めに終わりそうなコマンドを選択しました。それはheadコマンドでテキストの先頭を抜き出すだけという至ってシンプルなものです。文章の概要(サマリー)を作成する場合に便利です。OSなどの環境によって使用できるオプションが若干異なりますが、今回は共通のオプションしか使用しないのでLinuxでもMacでも動作します。(SunOSなど相当に古いUNIX環境でも動くはずです)

今回もこれまでのようにサンプルで利用するファイル・ディレクトリはデスクトップのsampleディレクトリとしています。デスクトップにsampleディレクトリがない場合は作成しておいてください。(コマンド入力ならmkdir ~/Desktop/sampleとして作成することができます)
また、カレントディレクトリも上記の場所になります。cd ~/Desktop/sampleのようにコマンドを入力してカレントディレクトリを変更しておけばよいでしょう。

先頭行を抜き出す

 まず、headコマンドでテキストの先頭を抜き出してみましょう。カレントディレクトリにあるテキストファイル1.txtの先頭行を抜き出すには以下のようにします。

head 1.txt

実行するとテキストの先頭から数行が表示されています。headコマンドはオプションを指定しない限り先頭から10行出力するようになっています。
指定した行数だけ出力する場合は-nを指定します。-nの後に出力する行数を指定します。以下のようにすると先頭1行だけが表示されます。

head -n 1 1.txt

先頭の3行なら以下のようになります。

head -n 3 1.txt

ちょっと行数がわかりにくいかもしれませんので、短い1行単位になっているファイル(5.txt)で実行してみましょう。

head -n 3 5.txt

複数ファイルの先頭1行を抜き出す

 次に複数のファイルから先頭1行だけを抜き出してみましょう。カレントディレクトリ内にある拡張子がtxtのテキストファイルであれば以下のようになります。

head -n 1 *.txt

カレントディレクトリ以下のサブディレクトリも含める場合は以下のようになります。この場合はfindコマンドを使います。-typeの後に指定するオプションの内容は以下のようになります。

f: 通常のファイル
d: ディレクトリ
l: シンボリックリンク


find . -name "*.txt" -type f

これで処理する対象ファイルが分かるので、後はパイプ(|)とxargsを利用してheadコマンドのnオプションを指定すれば対象ファイルの先頭一行が表示されます。

find . -name "*.txt" -type f | xargs head -n 1

xargsでなくfindコマンドのexecを使う方法もあります。

find . -name "*.txt" -type f -exec head -n 1 {} \;

バイト単位で抜き出す

 headコマンドはテキストをバイト単位で抜き出すこともできます。日本語などマルチバイト文字がない時代ではバイト単位で抜き出すということは1文字単位で抜き出すことになります。さすがに、マルチバイト・Unicode時代でバイト単位で抜き出すというのは無理があります。
 無理はありますが、ファイル内容が1バイトテキスト(英数字・記号のみといった英語文書など)で構成されているなどの条件を満たせば、使う場面もあるかもしれません。

 ファイル内容をバイト単位で抜き出すには-cの後に抜き出すバイト数(文字数ではありません)を指定します。英数字など1バイトの場合は、そのまま文字が表示されますが、2バイト文字になると期待通りに出力されません。以下のように指定すると先頭の1バイトが出力されます。

head -c 1 img.png

このような場合は16進数文字列にした方が見やすくなります。バイナリの値を16進数文字列にするにはxxdコマンドを使います。headで取り出した値をパイプ(|)を使ってxxdコマンドに渡します。

head -c 1 img.png | xxd

複数のバイトを抜き出す場合は以下のようになります。(16バイト抜き出して表示)

head -c 16 img.png | xxd

テキストのサマリー(概要)を作成する

 次に複数あるテキストファイルのサマリー(概要)を作成してみましょう。まずは、カレントディレクトリにあるテキストファイルのサマリーを作って、新たにテキストファイルとして保存します。

head -c 12 *.txt >summary.txt

同じディレクトリに保存してしまうと、次に同じコマンドを実行した時にsummary.txtの内容も処理されてしまうので、他のディレクトリに保存した方がよい場合もあります。ファイル名に生成時の日時を付加する(連載第53回参照 https://news.mynavi.jp/techplus/article/natonakucommand-53/)、シェルスクリプトで除外する方法もありますが、とりあえずデスクトップ上にsummary.txtを生成するには以下のようにします。環境によってはDesktopでなくデスクトップや類似する名称になっている事もあります。その場合は該当するDesktopのパス名を適宜置き換えてください。

 head -c 12 *.txt >~/Desktop/summary.txt

HTMLファイルに出力する

 それでは最後にWebブラウザでテキストファイルの先頭が閲覧できるようにしてみましょう。Webブラウザでテキストファイルの内容が確認できれば便利です。ここではシェルスクリプトで作ってみましょう。シェルはbashベースですが、特にbash特有の機能は使っていないのでzshでも動作します。

 まず、HTMLファイルのヘッダー部分です。これは別ファイルにしておくと楽ですが、今回はechoコマンドを使って一つのシェルスクリプトにすることにします。
 ます、HTML部分のヘッダーは以下のように最低限のものだけにします。テキストファイルをリスト表示するのでliタグを使ってリスト化します。

<!DOCTYPE>
<head><meta charset="utf8">
<title>summary</title>
</head><body><ul>

 <li>以下はシェルスクリプトで生成します。●●の部分がテキストファイルへのリンクパス(ファイルパス)になります。■の部分がheadコマンドで抜き出した文字列になります。これを検索して出てきたテキストファイルの数だけ繰り返します。

<li><a href="●●">■</a></li>

最後のフッターは以下のようになります。

</ul></body></html>

概要としては、こんな感じになります。それではシェルスクリプトを作成していきます。リスト部分以外をechoで生成するシェルスクリプトは以下のようになります。シェルスクリプトのファイル名はh.shとしてあります。

#!/bin/bash
echo '<!DOCTYPE>'
echo '<head><meta charset="utf8">'
echo '<title>summary</title>'
echo '</head><body><ul>'
echo ''
echo '</ul></body></html>'

テキストエディタで入力して保存します。保存したら実行権限を付加しておきます。実行権限はchmod u+xで追加することができます。
実行権限を付加したら./h.shと入力して実行します。
Windows (WSL) 上のエディタでシェルスクリプトを入力して実行させる場合、改行コードの違いで動作しないことがあります。
改行コードを変換するには以下のコマンドを入力します。

sed -i 's/\r$//' ./h.sh

正しく処理されると画面にHTMLタグの文字列が表示されます。

次にファイルのリスト生成部分です。これはforを使ってfindコマンドで見つかったファイルの数だけ繰り返します。コマンドの実行結果を利用するにはバッククオート(`)で囲みます。

for file in `find . -name "*.txt" -type f`

あとはechoを使ってファイル名とheadコマンドの結果を出力します。

do
  echo -n "<li><a href='$file'>"
  head -c 40 $file
  echo '</li>'
done

ここまでの処理をまとめると以下のようになります。

#!/bin/bash
echo '<!DOCTYPE>'
echo '<head><meta charset="utf8">'
echo '<title>summary</title>'
echo '</head><body><ul>'

for file in `find . -name "*.txt" -type f`
do
  echo -n "<li><a href='$file'>"
  head -c 40 $file
  echo '</li>'
done

echo '</ul></body></html>'

./h.shと入力して実行します。

期待通りの結果になっているようです。が、このままではブラウザで表示できません。とりあえず、file.htmlという名前で保存しておきましょう。この場合はリダイレクトを使って保存するだけです。

./h.sh >file.html

この記事は
Members+会員の方のみ御覧いただけます

ログイン/無料会員登録

会員サービスの詳細はこちら