mattintosh note

どこかのエンジニアモドキの備忘録

シェルスクリプトでカラム表示とかセンタリング表示とか

これも Qiita に投稿できないのでこっちに。

〈カラム表示〉

  • /usr/bin/column
  • /usr/bin/lam
  • /usr/bin/paste
  • /usr/bin/pr
  • /usr/bin/rs

〈テキスト生成・加工〉

  • /usr/bin/fmt:テキストのセンタリング
  • /usr/bin/fold:長くなったテキストを指定行で折り返す
  • /usr/bin/jot:連続・ランダムデータの生成

〈カラム表示〉

column

行をデリミタで分割してカラム表示するコマンド。一行あたり 2048 バイトまでの制限がある。

(
    echo "PERM LINKS OWNER GROUP SIZE MONTH DAY TIME NAME"
    /bin/ls -l / | tail -n +2
) | column -t
PERM         LINKS  OWNER  GROUP  SIZE      MONTH  DAY  TIME   NAME
drwxrwxr-x+  115    root   admin  3910      11     25   20:12  Applications
drwxrwxr-x@  17     root   admin  578       8      10   2012   Developer
:

デリミタの変更

( echo "YEAR-MONTH-DAY" ; date +%F ) | column -t -s -
YEAR  MONTH  DAY
2013  12     01

lam

入力を1行ごとに読み込んで並べるコマンド。

  • -f <min>.<max>:カラム間の幅を指定する。
  • -p <min>.<max>:カラム間の幅を指定する。-f と異なり空行にも適用される。
  • -s <string>:カラム間の区切りを <string> に指定する。
  • -t <char>:入力のデリミタを <char> に指定する。

-f-p の数値の先頭が - であった場合は左詰め指定、0 が指定された場合は 0 で敷き詰められる。また、読み込んだ行の内容が <max> を上回る場合はトリミングされ、<min> に満たない場合はスペースで敷き詰められる。各オプションが小文字であれば各カラム間に、大文字の場合はそれ以降のカラム間全てに適用される。

lam -P -8 /dev/fd/3 /dev/fd/4 3<<EOS1 4<<EOS2
one
two
three
EOS1
four
five
six
EOS2
one     four
two     five
three   six

入力に - が使用された場合は標準入力から1行ずつ読み込む。(paste コマンドも参照)

lam -P 06 -s "| " - -S " | " - - -s " |" <<EOS
1
20
300
4000
50000
600000
EOS
| 000001 | 000020 | 000300 |
| 004000 | 050000 | 600000 |

入力デリミタもファイルごとに変更可能。

lam -p 03 /dev/fd/3 -s ": " -t , /dev/fd/4 -s $'\n' 3<<EOS1 4<<EOS2
1
2
3
EOS1
foo,,bar,
EOS2
001: foo
002:
003: bar

左詰めの場合は幅に合わせてスペースで埋めるので余白の作成にも使える。

(
    echo center | fmt -cw40
    echo center | fmt -cw40 | lam -f -40 -
) | cat -e
                 center$
                 center                 $

paste

入力を並べるコマンド。ファイル名に - を指定した場合は標準入力から読み込む(複数回指定可能)。空行は <空> として処理される。カラム間は <tab> で区切られるのでスペースに変換する場合は expand などを用いる。

paste - - - <<EOS | expand
1 foo
2 bar
3 baz

5 hoge
6 piyo
EOS
1 foo   2 bar   3 baz
        5 hoge  6 piyo

sed= ファンクションで行を連結するのに使ったり。

/bin/ls / | sed = | paste - -
1 Applications
2   Developer
3   Library
:

デリミタは複数指定すると先頭から順に使用される。\n\t\0 などが使用可能。\0<nul> ではなく空の指定。

paste -d "\n:" - - - <<EOS
1
2
3
4
5
6
EOS
1
2:3
4
5:6

-s オプションを使用すると一行になる。

PATH=$(/usr/bin/paste -s -d : - <<EOS
/usr/bin
/bin
/usr/sbin
/sbin
EOS)
PATH=/usr/bin:/bin:/usr/sbin:/sbin

pr

  • -a:カラム表示の場合に並び順を変更する。
  • -d:各行に改行を追加する。
  • -e<char><gap>:入力の <char><gap> サイズに変更する。
  • -l <lines>:ページの行数を <lines> で上書きする。(デフォルトは66行)
  • -s<char>:カラム間を <char> で区切る。(デフォルトは <tab>
  • -n<char><width>:行番号を表示する。<width> は行番号部分の幅でデフォルトは5。<char> の指定がなければ <tab> で区切られる。
  • -w <width>:行幅を <width> に指定する。デフォルトは 72-w オプションが指定されておらず、-s オプションが指定されている場合は512。
  • -o <offset>:ページのオフセットをスペース <offset> 個に指定する。-o オプションが指定されていない場合はゼロ。
  • -t:上下の余白とヘッダを表示しない。

表示幅が足りないアイテムは途中でカットされるので注意。

/bin/ls / | pr -6 -t

タブ幅が8の場合に綺麗に並んで表示される。

Application System    bin     home    private     var
Developer   User Guides cores       mach_kernel sbin
Library     Users   dev     net     tmp
Network     Volumes etc     opt     usr

タブではなくスペースで出力する場合は -i" "1 で出力するか expand などで変換する。

/bin/ls / | pr -6 -t -i" "1
/bin/ls / | pr -6 -t | expand
Application System      bin         home        private     var
Developer   User Guides cores       mach_kernel sbin
Library     Users       dev         net         tmp
Network     Volumes     etc         opt         usr

-a オプションを使用すると表示順の変更ができる。

(
/bin/ls / | pr -2 -t -n
/bin/ls / | pr -2 -t -n -a
) | expand
    1   Applications                     12     etc
    2   Developer                        13     home
    3   Library                          14     mach_kernel
    :
    :
    1   Applications                      2     Developer
    3   Library                           4     Network
    5   System                            6     User Guides and Information
    :
    :

二つのファイルを左右に並べて表示する

pr -t -w 164 -m <( man 1 printf | col -bx ) <( man 3 printf | col -bx )

ページを割り付け印刷状に表示する

man pr | col -bx | pr -2 -w 164

rs

  • -c<c>:入力を <c> で区切る。-e の指定がある場合は無効。<c> が省略された場合は <tab>
  • -s<c>:入力を <c> で区切るが、<c> が連続していても1つとして扱う。-e の指定がある場合は無効。
  • -C<c>:出力カラム間を <c> で区切る。<c> が省略された場合は <tab>
  • -S<c>:出力カラム間を <c> で埋める。
  • -k<n>:入力の <n> 行を無視する。
  • -K<n>:入力の <n> 行を無視するが印字する。
  • -g<n>:カラム間の溝を <n> に指定する。デフォルトは 2
  • -G<n>:カラム間の溝をそれを含めた最大幅の <n> パーセントで指定する。(?)
  • -e:入力を行ごとに処理する。
  • -t:出力順を変更する。
  • -T<rows><cols> を無視して並べる。
  • -z:カラム間を詰める。
  • -n:空エントリを詰めない。
  • -w<n>:ページ幅を <n> に指定する。(デフォルトは80)
  • -j:カラム内を右寄せにする。
  • -h:配列の数を表示する。
  • -H:配列の数を表示する。(-h を更にラインごとに分解)

<rows> もしくは <cols>0"" を指定した場合はもう一方の値で自動生成される。-w の指定がある場合は幅に合わせてカラム数が調整される。

/bin/ls / | rs -etz 0 5
Applications  User Guides and Information  dev          opt      var
Developer     Users                        etc          private  
Library       Volumes                      home         sbin     
Network       bin                          mach_kernel  tmp      
System        cores                        net          usr      

〈テキスト生成・加工〉

fmt

テキストのセンタリング

(
    n=40
    jot -b = -s "" ${n}
    date +%+ | fmt -c -w ${n}
    jot -b = -s "" ${n}
)
========================================
      Sun Dec  1 00:00:00 JST 2013
========================================

fold

テキストの折り返し

jot -b - -s "" 40
jot -b - -s "" 40 | fold -w 10
----------------------------------------
----------
----------
----------
----------

jot

シーケンシャル・ランダムデータ出力コマンド。同じ文字を複数回出力したりする場合に便利。

  • -r:ランダムなデータを生成する。
  • -b:<word> word を出力する。
  • -w:<word> 生成されたデータを追加して word を出力する。
  • -c-w %c と同じ。
  • -s:string データの区切りを string に指定する。(デフォルトは改行)
  • -n:最後の改行を出力しない。

1から100まで出力する

jot 100
1
2
3
:
100
jot -w %03d 100
001
002
003
:
100

A-Za-z までを出力する

(
    jot -n -s "" -c 26 A
    jot -n -s "" -c 26 a
)
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

あるパターンを○回繰り返して出力する

jot -b - -s "" 32
jot -b "-------+" -s "" 4
--------------------------------
-------+-------+-------+-------+

ASCII コード表

man ascii が見づらかったので作ってみた。

#!/bin/sh

cs=$'\033[1;31m'
ce=$'\033[m'

/usr/bin/jot -n -s "" -c 128 0 \
| /usr/bin/hexdump -f /dev/fd/3 3<<EOS
1/1 "${cs}%3_u${ce}" 15/1 "  ${cs}%3_u${ce}" "\n"
1/1 "%3_c"           15/1 "  %3_c"           "\n"
1/1 "%3d"            15/1 "  %3d"            "\n"
1/1 "%03o"           15/1 "  %03o"           "\n"
1/1 " %02x"          15/1 "   %02x"          "\n"
"$(/usr/bin/jot -b - -s "" $((5 * 16 - 2)))" "\n"
EOS
nul  soh  stx  etx  eot  enq  ack  bel   bs   ht   lf   vt   ff   cr   so   si
 \0  001  002  003  004  005  006   \a   \b   \t   \n   \v   \f   \r  016  017
  0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15
000  001  002  003  004  005  006  007  010  011  012  013  014  015  016  017
 00   01   02   03   04   05   06   07   08   09   0a   0b   0c   0d   0e   0f
------------------------------------------------------------------------------
dle  dc1  dc2  dc3  dc4  nak  syn  etb  can   em  sub  esc   fs   gs   rs   us
020  021  022  023  024  025  026  027  030  031  032  033  034  035  036  037
 16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31
020  021  022  023  024  025  026  027  030  031  032  033  034  035  036  037
 10   11   12   13   14   15   16   17   18   19   1a   1b   1c   1d   1e   1f
------------------------------------------------------------------------------
: