シェルスクリプトで上下左右から何文字か切り取る方法(行列の操作)

2022-08-14Bash

はじめに

シェルスクリプトで上下左右から文字列を切り取る方法について。
共通したコマンドがないため、いくつかのコマンドを組み合わせて実現することになります。

検証環境

$ uname -moi
x86_64 x86_64 GNU/Linux

$ bash -version | head -n 1
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)

準備

以下のコマンドを実行し、操作対象のテキストファイルを作成します。

# 2重ループさせる
$ (
    for i in {0..9}; do
      echo -n $i
      for j in {1..9}; do echo -n $j; done
      echo
    done
  ) >sample.txt

# 一番左の列に0から始まる行番号が出力されている
$ cat sample.txt
0123456789
1123456789
2123456789
3123456789
4123456789
5123456789
6123456789
7123456789
8123456789
9123456789

いろいろな切り取り方法

上から2行切り取り

sed コマンドを利用する方法があります。

$ cat sample.txt | sed '1,2d'
2123456789
3123456789
4123456789
5123456789
6123456789
7123456789
8123456789
9123456789

tail コマンドを利用する方法もあります。
( プラス + 記号をつけるのがポイントです。 )

$ cat sample.txt | tail -n +3
2123456789
3123456789
4123456789
5123456789
6123456789
7123456789
8123456789
9123456789

下から2行切り取り

sed コマンドを利用する方法がありますが、事前に行数を調べるために wc -l を利用しなければならないためスマートとは言えません。

# パイプの後ろは "sed 8,$d" と同義
$ cat sample.txt | sed $(($(wc -l < sample.txt)-1))',$d'
0123456789
1123456789
2123456789
3123456789
4123456789
5123456789
6123456789
7123456789

head コマンドを利用するのが簡単でしょう。
( tail の時とは反対に マイナス - 記号をつけるのがポイントです。 )

$ cat sample.txt | head -n -2
0123456789
1123456789
2123456789
3123456789
4123456789
5123456789
6123456789
7123456789

左から2列切り取り

sed コマンドを使う方法。

$ cat sample.txt | sed 's/^.\{2\}//'
23456789
23456789
23456789
23456789
23456789
23456789
23456789
23456789
23456789
23456789

cut コマンドを使う方法。
こちらは 3文字目以降を出力する という意味になります。

$ cat sample.txt | cut -c3-
23456789
23456789
23456789
23456789
23456789
23456789
23456789
23456789
23456789
23456789

右から2列切り取り

sed コマンドを使う方法。

$ cat sample.txt | sed 's/.\{2\}$//'
01234567
11234567
21234567
31234567
41234567
51234567
61234567
71234567
81234567
91234567

cut コマンドを使う方法。
こちらは 8文字目までを出力する という意味になります。

※こちらも予め列数を把握しておかないといけないという問題があります。

$ cat sample.txt | cut -c-8
01234567
11234567
21234567
31234567
41234567
51234567
61234567
71234567
81234567
91234567

その他の方法

head / tail / sed のコマンド使い分けが面倒という方向けに、 tt というコマンドを作成しました。
Githubで公開しています。

こちら、Dockerイメージとしても公開しています。
使い方は以下のようになります。

# 上下左右から1文字ずつ切り取る
$ cat sample.txt | docker run -i genzouw/trim-text -t1 -b1 -l1 -r1 

ひとこと

まとめるとおすすめの方法は以下のとおりです。

  • 「上」をtrimする : tail コマンド
  • 「下」をtrimする : head コマンド
  • 「左右」をtrimする : sed コマンド

2022-08-14Bash