12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Bashでコマンド出力結果を使ってコマンドを実行する方法

Last updated at Posted at 2022-05-30

はじめに

LinuxのBashでコマンド操作を行なっている際に、コマンドが出力した結果をそのままコマンドとして利用したり、実行したいと思う場面に遭遇する事があるかと思いますが、その場合の対応方法について紹介します。

例えばファイル名のプレフィックスを誤って付与して複数ファイルを生成してしまいファイル名を変更したい場合、リネームするためのコマンドを生成したものの、この後どうやって生成したコマンドを実行しよう...となってしまった場合などが上記に該当します。

プレフィックスのhoge1をhoge2に変更するコマンドを生成
$ ls
hoge1_20220530.dmp  hoge1_20220530.png  hoge1_20220530.txt
$ ls | sed -e 's/^\(.*\)/mv \1 :\1/' -e 's/:hoge1/hoge2/'
mv hoge1_20220530.dmp hoge2_20220530.dmp
mv hoge1_20220530.png hoge2_20220530.png
mv hoge1_20220530.txt hoge2_20220530.txt
$ 

・コンソールにコマンドを貼り付ける

コマンドの出力結果を一行コピーしてコンソールに貼り付けて実行、終わったら次の一行をコピーしてコンソールに貼り付けて実行...と繰り返し行う事もできますが、大量に行数があった場合に作業が面倒になります。

意外と知られていませんがコンソールにコマンドを貼り付けて実行する場合に複数行のコピー結果をコンソールに貼り付ける事ができます。
また、貼り付けられてたコマンドは上から順番に実行されますので、わざわざ一行一行実行されるのを待つ必要はありません。

上記の例でいうと、コマンド出力結果の下記3行を改行と一緒にコピーしてコンソールに貼り付けを行うと、そのまま3つのコマンドが上から順次実行されて行きます。

mv hoge1_20220530.dmp hoge2_20220530.dmp
mv hoge1_20220530.png hoge2_20220530.png
mv hoge1_20220530.txt hoge2_20220530.txt

1つのコマンドに時間がかかる処理でも同様に実行してくれるので、テキストエディタなどに記載した複数のコマンドを手っ取り早く実行する際にも役に立ちます。

bashコマンドを使用する

コマンドを実行する際のShellとして認識されているBashですが、実はbashというコマンドが用意されており、それを利用してコマンド出力結果を使ってコマンドを実行する事ができます。

具体的にはコマンドの出力結果をパイプ|で繋いでbashコマンドに渡す事で、渡された出力結果のテキストをコマンドとして実行してくれます。

プレフィックスのhoge1をhoge2にmvする(bashコマンド使用)
$ ls | sed -e 's/^\(.*\)/mv \1 :\1/' -e 's/:hoge1/hoge2/' | bash
$  

末尾に | bash をつけるだけなので簡単でわかりやすくオススメの実行方法です。

xargsコマンドを使用する

コマンドの引数を動的に作成して実行するための代表的なコマンドとしてxargsコマンドがありますが、このコマンドを利用してコマンド出力結果を使ってコマンドを実行する事ができます。

具体的にはコマンドの出力結果をパイプ|で繋いでxargsコマンドに通じて一行ずつshコマンドの引数として渡す事で、渡された出力結果のテキストをコマンドとして実行してくれます。

プレフィックスのhoge1をhoge2にmvする(xargsコマンド使用)
$ ls | sed -e 's/^\(.*\)/mv \1 :\1/' -e 's/:hoge1/hoge2/' | xargs -IX sh -c "X"
$ 

また、せっかくxargsコマンドを使用するのであればリネームするためのmvコマンドをxargsコマンドに持ってくる方がスッキリした記述ができます。

プレフィックスのhoge1をhoge2にmvする(xargsコマンド使用)
$ ls | sed -e 's/^\(.*\)/\1 :\1/' -e 's/:hoge1/hoge2/' | xargs -L1 mv
$ 

bashコマンドの方が簡単でわかりやすいのでわざわざxargsコマンドを使う必要はありませんが、引数も動的に変える場合や、時間のかかるコマンドを-Pオプションを使用して複数同時に実行する場合などに重宝します。

3コマンド同時並行で実行
$ ls | sed -e 's/^\(.*\)/mv \1 :\1/' -e 's/:hoge1/hoge2/' | xargs -P3 -IX sh -c "X"
$ 

今回は単純に出力結果を使用してコマンドを実行するだけなのでxargsコマンド自体の詳細な説明は割愛させて頂きますが、非常に便利で強力なコマンドなので興味のある方は是非調べてみてください。

sedコマンドを使用する

今回の例でもコマンド出力結果のテキストを加工するために使用したsedコマンドですが、引数のスクリプトコマンドにeを指定する事でテキストをコマンドとして実行する事ができます。

プレフィックスのhoge1をhoge2にmvする(sedコマンド使用)
$ ls | sed -e 's/^\(.*\)/mv \1 :\1/' -e 's/:hoge1/hoge2/e'
$ 

上記では置換処理を行なった後にコマンドの実行を行なっていますが、わかりやすくするためにlsという文字列をsedコマンドに渡し、置換せずに実行したものを下記に記載します。

echoでlsという文字列を出力し、パイプでsedに渡してlsを実行
$ echo ls
ls
$ echo ls | sed 'e'
hoge1_20220530.dmp
hoge1_20220530.png
hoge1_20220530.txt
$ 

また、簡単な置換処理を行なった後にコマンドを実行したものを下記に記載します。

echoでlsという文字列を出力し、パイプでsedに渡して-aオプションを指定してlsを実行(ls -aを実行)
$ echo ls | sed 's/$/ -a/e'
.
..
hoge1_20220530.dmp
hoge1_20220530.png
hoge1_20220530.txt
$ 

この様に実行したいコマンドを作成しながら実行もできるので非常に使いやすく、sedコマンドそのものも非常に強力なため慣れてくると一番活躍する実行方法になるのではないかと思います。

・コマンド置換$()を使用する

Bashにはコマンドの出力結果を置き換えるコマンド置換($())という機能があり、この機能を利用してコマンドの出力結果をそのままコマンドとして実行する事ができます。

lsをコマンド置換で実行
$ echo ls | $(cat -)
hoge1.txt  hoge2.txt
$ 

通常コマンド置換は変数にコマンド実行結果を格納するのに使用されますが、この様にコマンド実行結果をそのままコマンドとして使用することもできます。
ただ、一行のコマンドしか実行できず非常にわかり難いため、この方法を使用するより素直にbashコマンドを使用する方が良いと思います。

findコマンドを使用する

コマンドの実行結果をそのままコマンドとして実行する訳ではないのですが、findコマンドでも見つけたファイルに対してコマンドを実行する事ができます。

例えば先ほどの例で紹介していたファイルのリネームについてもfindコマンドであればスッキリ記述する事ができます。

ファイルのプレフィックスであるhoge1をhoge2に変更
$ find ./ -exec rename hoge1 hoge2 "{}" \;
$ 

この様に、検索したファイルに対してアクションを起こしたい場合はfindコマンドでできる事が以外と多く、またxargsコマンドを組み合わせて使うことも多いので参考までに記載しておきます。

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?