シェルスクリプトでファイルや標準出力を最終行から逆順に出力する「tac」コマンド

2020-01-17Bash

はじめに

Coding Games で遊んでいたときに標準入力で受け取った内容を逆に処理しないといけないことがありました。
めったに使うことはないのですが「tac」コマンドを使ったので、取り上げてみたいと思います。

検証環境

$ uname -moi
x86_64 MacBookPro10,1 Darwin

$ bash -version
GNU bash, バージョン 5.0.3(1)-release (x86_64-apple-darwin18.2.0)

$ tac --version
tac (GNU coreutils) 8.31

準備

Linux環境であれば、おそらくすでにインストール済みです。

Mac環境の場合、デフォルトではインストールされていないそうです。
僕の環境にはインストールされていましたが、おそらく以下のコマンドでインストールされたと思われます。

以下のコマンドで、 GNU のコアコマンドを一式インストールしてくれます。

$ brew install coreutils \
  --with-default-names

使い方

はじめに触れましたが、ファイルや標準出力を最終行から逆順に出力できます。

例を上げてみます。

# 実行すると1〜5までの数値が出力される
$ seq 1 5
1
2
3
4
5

# `tac` コマンドを使ってみる
$ seq 1 5 | tac
5
4
3
2
1

# でも、これだけであれば `sort` コマンドで十分では?
$ seq 1 5 | sort -nr
5
4
3
2
1

seq の実行結果が逆に出力されました。めでたしめでたし。。。とはならないですね。
この例だと sort -nr でも十分ではないか?と思われてしまいます。

別のサンプルファイルを作成します。
Bashシェルスクリプトでランダムな数列を生成する2つの方法 を参考にランダムな数値のファイルを作成します。

# 1〜5の数値をランダムに出力したファイルを作成
$ seq 1 5 | shuf > data.txt

# 内容を確認
$ cat data.txt
5
1
3
2
4

# `tac` コマンドを使ってみる
$ cat data.txt | tac
4
2
3
1
5

# `cat` を使わなくてもよい
$ tac data.txt
4
2
3
1
5

ファイルや標準出力の内容が逆に出力されていることがわかります。

ひとこと

実際あんまりつかうことないんですよね。
以前 sed開始アドレス、終了アドレス と組み合わせてなにかしようとしたときに逆順にしてから sed すると処理しやすくて大発見や!と思っていたんですが、どんなときに使ったのか思い出せず…

2020-01-17Bash