sedのe内部コマンドで指定された文字列をシェルコマンドとして実行させる

Bash

はじめに

sed コマンドの e 内部コマンドで指定された「文字列」をシェルコマンドと見直して実行させることができます。
文章だけではわかりにくいので例を上げて説明したいと思います。

僕はこちらの機能をほとんど利用したことはありませんが、こういう機能もあるということで取り上げてみます。

検証環境

$ uname -moi
x86_64 MacBookPro11,4 Darwin
$ bash -version
GNU bash, バージョン 5.0.7(1)-release (x86_64-apple-darwin18.5.0)
$ sed --version
sed (GNU sed) 4.2.2

準備

テストデータを用意します。
各行に1から20の値を出力したファイルになります。

$ seq 1 20 > test.txt
# 最後の10行を表示
$ tail test.txt
11
12
13
14
15
16
17
18
19
20

0がつく文字列のときだけ時刻を表示させる

0がつく文字列のときだけ、 date コマンドで時刻を表示させてみます。

$ cat test.txt | sed '/0/e date;'
1
2
3
4
5
6
7
8
9
Sun May 12 23:28:00 UTC 2019
10
11
12
13
14
15
16
17
18
19
Sun May 12 23:28:00 UTC 2019
20

もともとの数値( 10 / 20)も表示させてしまっているため、削除ロジックも追加してみます。

$ cat test.txt | sed '/0/e date;
/0/d;
'
1
2
3
4
5
6
7
8
9
Sun May 12 23:29:16 UTC 2019
11
12
13
14
15
16
17
18
19
Sun May 12 23:29:16 UTC 2019

sedで置換した結果をシェルコマンドとして実行する

lsof という文字列を置換し、 ls コマンドを実行させてみます。

$ echo lsof | sed 's@of@@e'
anaconda-ks.cfg
test.txt

少し修正し、 /etc ディレクトリを ls を実行させてみます。

$ echo lsof | sed 's@\(.*\)of@\1 /etc @e'
BUILDTIME
DIR_COLORS
DIR_COLORS.256color
DIR_COLORS.lightbgcolor
GREP_COLORS
X11
adjtime.rpmsave
...
(省略)

「だからなに?」というような例になってしまいました。。。

ひとこと

今ひとつ上手い使い方が思いつかない e 内部コマンドでした。
xargs 使うか、速度的には懸念があるがループを回すかしたほうがいろいろできますしわかりやすいです。

Bash