perlとsedでtacする

6-2.並び替え


アニメ『ガヴリールドロップアウト』(2017)
天使学校を主席で卒業したにもかかわらず、人間界ではぐうたら生活。およそ天使らしくないガヴリールとその仲間のコメディです。外界に降りた直後は、部屋の掃除も公園のゴミ拾いまでもしてたのに、やはりオンラインゲームにはまるといろいろダメになってしまうんですねえ。やはりゲームはオフラインに限るっ。

ではコマンド天使技です。(神業とは呼べないぐらい使わない)

tacコマンド自体は神コマンドで、ものすごく簡潔にコマンドが入力できて、しかも覚えやすいコマンドです。

takk@deb83:~/blog/src$ seq 10 | tac
10
9
8
7
6
5
4
3
2
1
takk@deb83:~/blog/src$ 

このようにseqコマンドの表示を簡単に上下ひっくり返すことができますが、どうしてもtacを使いたくないとき(どういう時か分かりませんが)、perlやsedでtacと同じことをやる方法を考えてみます。

perlでは直感的です。配列に1から順に上方向へ文字列を逆に積み上げていき、最後に上から下へ表示するだけです。

takk@deb83:~/blog/src$ seq 10 | perl -ne 'unshift @a,$_;END{print @a}'
10
9
8
7
6
5
4
3
2
1
takk@deb83:~/blog/src$ 

sedではハノイの塔的なゲームのようです。パターンスペースとホールドスペースを使って試行錯誤します。

takk@deb83:~/blog/src$ seq 10 | sed -ne '1x;1d;G;h;$p'
10
9
8
7
6
5
4
3
2
1
takk@deb83:~/blog/src$ 

seq 10の結果の一行目を処理するときは、パターンスペースとホールドスペースの内容は下図のようになっています。

1xは、1行目でパターンスペースとホールドスペースを入れ替えるコマンドです。

パターンスペースには、ホールドスペースが持っていた空行が保存されているため、残しておくと余分な空行が表示されてしまいます。1行目の処理時にパターンスペースの空行を削除するため1dコマンドを実行します。

Gコマンドが、上下逆にするための末尾への追加コマンドとなります。ホールドスペースの全行の内容をパターンスペースの末尾に追加します。

あくまでも文字列を恒久的にホールド(保持)するのは、ホールドスペースのため、hコマンドでパターンスペースからホールドスペースへコピーします。パターンスペースは、毎行新しい文字列で更新されてしまうからです。

2行目の処理です。後は繰り返しになります。

9行目の処理です。最終的に10行目を処理するときに、$pコマンドによりパターンスペースの内容を表示することになります。このとき、パターンスペースにはseq 10 の結果を上下逆にしたテキストが格納されていますので、tacと同じ結果となるわけです。

コメント

タイトルとURLをコピーしました