【sed】変数に格納したコマンドの実行方法

このQ&Aのポイント
  • 変数に格納したsedコマンドを実行するにはどのようにすればいいでしょうか?
  • 質問内容は、変数に格納したsedコマンドを実行する際に発生するエラーについてです。
  • シェルスクリプトを使用してsedコマンドを実行している場合、変数内のコマンドを正しく実行する方法を教えてください。
回答を見る
  • ベストアンサー

【sed】変数に設定したコマンドの実行について

お世話になります。 一度変数に文字列として格納したsedコマンドの実行についての質問です。 以下、「実装1」のように、「あるファイルの最終行を除外して別のファイルに書き込む」という処理を行おうとしています。 ログ出力などの関係で、実行するコマンドを一度変数に格納する必要があるのですが 一度変数に格納して実行すると「実装2」のようにエラーが出てしまいます。 変数に格納したsedコマンドを実行するにはどのようにすればいいでしょうか? なお、シェルはbashです。 実行例ではターミナルから直接実行していますが、実際にはシェルスクリプトにして実行します。 以上、どなたかご教示頂けないでしょうか。 ■実装1 [root@localhost tmp]# cat /tmp/data aaa bbb ccc [root@localhost tmp]# sed -e '$d' /tmp/data >/tmp/data2 [root@localhost tmp]# cat /tmp/data2 aaa bbb [root@localhost tmp]# ■実装2 [root@localhost tmp]# CMD='sed -e $d /tmp/data >/tmp/data2' [root@localhost tmp]# echo $CMD sed -e $d /tmp/data >/tmp/data2 [root@localhost tmp]# $CMD aaa bbb sed: >/tmp/data2を読み込めません: そのようなファイルやディレクトリはありません [root@localhost tmp]#

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.2

No1です。 その理解で合ってます。 それら3処理以外にも * 等のファイルマッチの展開や、" ' \ によるクォート外しとかありますが。

Reghorn
質問者

お礼

>それら3処理以外にも * 等のファイルマッチの展開や、" ' \ によるクォート外しとかありますが。 なるほど、他の処理については機会があったら調べてみます。 本件解決しましたのでBAとさせて頂きます。 迅速な回答大変有難うございました。

その他の回答 (1)

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.1

$CMDの変数展開の前にリダイレクトの解釈がされるので、>/tmp/data2 がファイルへのリダイレクト指定で無く、>まで含めたファイル名として扱われます。 変数内のリダイレクトを処理するためには、evalが必要。evalするので$にはクォートが必要。 $ CMD='sed -e \$d /tmp/data >/tmp/data2' $ echo $CMD sed -e \$d /tmp/data >/tmp/data2 $ eval $CMD

Reghorn
質問者

お礼

早々の回答ありがとうございます。 回答頂きました通り、evalコマンドをかませることで動作することを確認致しました。 >$CMDの変数展開の前にリダイレクトの解釈がされるので、>/tmp/data2 がファイルへのリダイレクト指定で無く、>まで含めたファイル名として扱われます。 細かな話で申し訳無いのですが、この部分が理解できていません。 次のような解釈で合っていますでしょうか?(散らかった文章ですいません) (1)通常シェルは次の順にコマンドを処理する。 ・リダイレクトの解釈 ・変数の展開 ・コマンドの実行 (2)今回の実装2では「リダイレクトの解釈」の時点で$CMDが展開されていなかったため   $CMDのリダイレクト部分は、sedの変数の1つとして扱われた。 (3)evalコマンドを使用することで、上記3処理が2回走り、次のような処理になったためうまく動いた。 ・リダイレクトの解釈 … eval $CMDのためリダイレクトなし ・変数の展開 … eval sed -e \$d /tmp/data >/tmp/data2 ・コマンドの実行 … ※evalの引数でもう一周 ・リダイレクトの解釈 … sed -e $d /tmp/data >/tmp/data2 のためdata2に書き込み ・変数の展開 … 変数なし ・コマンドの実行 … sed -e $d /tmp/data >/tmp/data2 以上、よろしくお願いします。

関連するQ&A

  • solarisのシェルについて(sedコマンド)

    こんにちわ solarisのBシェルを現在使用しているのですが、 sedコマンドを使用して"を消したいのです。 具体的には # cat /tmp/test.log |sed | sed -e "s/"//g" というようなコマンドを打ちたいのですが、 この場合はどのようにすればよいのでしょうか? よろしくお願いします。

  • sedコマンドをシェルで実行でうまくいかない

    sedコマンドをシェルで実行しようとしています。 sedコマンドの引数がシングルクォートのためうまく出来ずに困っています。 テキスト内の /abc を xxx と変えたいとします。 以下のように作ってみました。 #!/bin/sh a='\/abc' b=xxx sed \'$a/$b\' txt しかし 認識できないコマンドです: '\/abc/xxx' というエラーが出ます。 $aで扱いたい変数は実はもっと長いパスの為、 ぜひ変数を使いたいのですが、うまくやる方法は無いでしょうか。

  • ブランクを含む環境変数の置換

    こんにちは。 今、UNIX上でファイルのある文字をある環境変数で置換するようなシェルを作成中です。 そこで、以下のようにsedを使用してみました。 cat AAA.txt |sed s/CurFY/`echo $FY`/g AAA.txtの内容 AAA BBB CurFY この時、環境変数$FYがブランクを含まない値の場合 はうまくCurFYを$FYの値に変更できるのですが、$FYに ブランクが入っていた場合は実行できません。 実行例) setenv FY "ACT 2003" cat AAA.txt |sed s/CurFY/`echo $FY`/g sed: コマンドが正しくありません: s/CurFY/ACT となってしまいます。 何かうまい方法はないでしょうか? どうかアドバイスお願いいたします。

  • Linux sedコマンド 特定行の置換

    こんにちは テキストファイルの内容をsedコマンドで特定の行の頭に#を付けるようにしたいのですが、 うまくいきません。どのようにしたら良いでしょうか。 --実行前の内容-- * * * * * /tmp/tst.sh * * * * * /opt/aaa.sh --想定結果-- #* * * * * /tmp/tst.sh * * * * * /opt/aaa.sh

  • コマンド実行結果を環境変数に代入する方法ありますか

    下記のとおりfindコマンドを実行すると結果が表示されます。 findコマンドの実行結果を直接環境変数に代入したいのですが、 できますでしょうか。 できれば「5」だけを環境変数に代入したいです。 よろしくお願いします。 C:\tmp>find /C "OPEN" aaa.txt ---------- AAA.TXT: 5

  • sedコマンドでのエスケープ文字の扱い

    はじめまして。Linuxのsedコマンドで困っています。 sedの置換文字列として連続する\をリテラルとする処理を考えていますが、\がいくつ入ってくるか(変数)、わからない場合において、複雑な処理なしに対処できないか、考えています。 ↓簡単な例ですが、コマンドベースで説明すると以下のようなものです。 $ var='\\' $ cat file.txt aa $ sed "s/.*/$var/" file.txt \ という結果になりますが、置換文字を変数から取る際に、連続する\が設定されるケースを想定したプログラムを組むたいと思っています。 \が入ってくる個数がわかるのであれば、\を2倍にセットしておけばできそうですが、いくつセットされてくるかはわからない場合、何かよい方法はないでしょうか。 念のため、Linux環境で、GNU sed 4.1.2版で試行しています。シェルはbashです。よろしくお願いします。

  • sedの引数を変数に格納する方法

    例えば、次のコマンド echo a b c d e f | sed -e 's/.*\(b.*e\).*/\1/' -e 's/.*b c *\(.*\) .*/\1/' の「-e 's/.*\(b.*e\).*/\1/' -e 's/.*b c *\(.*\) .*/\1/'」の部分を変数に格納して echo a b c d e f | sed $regex のように実行したいのですが、変数が展開されるときにクォーテーションマークがどのように付与されるのかを理解できず、 regex=’-e s/.*\(b.*e\).*/\1/' まではできたのですが、コマンドにスペースが入った場合、どうすれば良いのかわからないため、後半のコマンドを格納することができません。 この場合、どのように変数に格納すれば良いのでしょうか。 よろしくお願いいたします。

  • sed コマンドについて

    はじめまして 当方、初心者で勉強の身です。ご回答頂けたら幸いです。 linuxのシェルファイルが100以上あり、こちらの全ファイル内に含まれる文字列"ABCDE"を文字列"12345"に置換をしたいと思っています。 sed コマンドで sed -e "s/ABCDE/12345/g" *.csh のように実行しても、画面上に変換後が表示されるだけで その後、ファイルを見ても置換されていません。 どのようにすれば、全ファイルが修正されるのでしょうか。 以上です。回答の方をよろしくお願い致します。

  • シェルスクリプトのコマンド グループ化における変数の有効範囲について教

    シェルスクリプトのコマンド グループ化における変数の有効範囲について教えてください。 中括弧"{ }"を使うと親プロセス(=その実行中のプロセス)にて実行、 小括弧"( )"を使うとサブシェル(=子プロセス)にて実行されると認識しています。 また環境変数は子プロセスに引き継がれ、シェル変数は引き継がれないと認識しています。 以下のシェルスクリプト(Bシェル)でテストしたところ、続くような結果となりました。 ~スクリプト内容~ #!/bin/sh ##TEST1 VAR01=AAA { echo 中括弧内でVAR01は${VAR01}; } ( echo 小括弧内でVAR01は${VAR01}; ) ##TEST2 { VAR02=BBB; echo 中括弧内でVAR02は${VAR02}; } echo 外でVAR02は${VAR02} ##TEST3 ( VAR03=CCC; echo 小括弧内でVAR03は${VAR03}; ) echo 外でVAR03は${VAR03} ~実行結果~ 中括弧内でVAR01はAAA 小括弧内でVAR01はAAA 中括弧内でVAR02はBBB 外でVAR02はBBB 小括弧内でVAR03はCCC 外でVAR03は  VAR02、VAR03の結果は納得できます。 またVAR01が{ }に引き継がれているのも納得できました。 しかし、VAR01はシェル変数として作成した(exportによる環境変数化はしていない)にも関わらず、子プロセスである( )内処理にも引き継がれているのはなぜなのでしょうか? 

  • シェルスクリプト コマンドを変数にした時の呼び方

    はじめまして、シェルスクリプトを勉強中の者です。 コマンドを変数にいれて、まとめました。 しかしコマンドの変数を呼びこもうとするとエラーになります。 ============================================ #!/bin/sh GREP="grep" cat "${GREP} '^[0-9]' /home/hoge/test.nicdf" ============================================ ================ シェル実行結果 ============= $ ./test.sh cat: grep '^[0-9]' /home/hoge/test.nicdf: そのようなファイルやディレクトリはありません どう書けば、エラーにならずに正常に動作するでしょうか? ご教授の程よろしくお願いします。

専門家に質問してみよう