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

このQ&Aのポイント
  • sedコマンドで引数を変数に格納する方法を理解したいです。
  • 変数にsedコマンドの引数を格納する方法について教えてください。
  • sedの引数を変数に代入する方法が分かりません。
回答を見る
  • ベストアンサー

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/' まではできたのですが、コマンドにスペースが入った場合、どうすれば良いのかわからないため、後半のコマンドを格納することができません。 この場合、どのように変数に格納すれば良いのでしょうか。 よろしくお願いいたします。

  • inshin
  • お礼率78% (104/133)

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

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

evalを使わないと駄目みたいです。 regex='-e "s/.*\(b.*e\).*/\1/" -e "s/.*b c *\(.*\) .*/\1/"' echo a b c d e f | eval sed $regex

inshin
質問者

お礼

ご回答いただきまして、ありがとうございます。 エスケープで対応できないのはなぜでしょうか? よろしくお願いいたします。

その他の回答 (2)

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

>クォートが本来のクォートとして機能せず、文字として認識されるという意味でしょうか? はいそういう意味です。 A="'*'" echo $A ⇒ '*' と、クォートが効いているように見えるが、 touch "'foo'" ls ⇒ 'foo' echo $A ⇒ 'foo' と、「'*'」は「'」で始まり「'」で終わるファイル名にマッチする

inshin
質問者

お礼

そういうことでしたか。ありがとうございました。

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

>エスケープで対応できないのはなぜでしょうか? クォートを外す処理の方が、変数展開よりも先に行われるため、変数内のクォートは除去されません。なので、クォートが残ってしまい、【未知のコマンドです: 「"」】のようなエラーになります。

inshin
質問者

お礼

ご回答いただきまして、ありがとうございます。 すみません、「クォートを外す処理が展開より先に行われ、クォートが残る」のイメージが湧きません^^; クォートが本来のクォートとして機能せず、文字として認識されるという意味でしょうか?

関連するQ&A

  • sedで置換した値を変数にセットしたい。

    sedで置換した値を変数にセットしたい。 次のように変数aaにセットした文字列「abc」を「abd」に置換して、再度変数aaにセットしたいのですがうまくいきません。 # aa=abc # aa=`echo $aa | sed -e 's/c/d/'` sed: -e 表現 #1, 文字数 5: 「s」コマンドが終了していません # 宜しくお願いします。

  • sedで置換した値を変数にセットしたい。

    sedで置換した値を変数にセットしたい。 次のように変数aaにセットした文字列「abc」を「abd」に置換して、再度変数aaにセットしたいのですがうまくいきません。 # aa=abc # aa=`echo $aa | sed -e 's/c/d/'` sed: -e 表現 #1, 文字数 5: 「s」コマンドが終了していません # 宜しくお願いします。

  • Q>変数をsedで編集する方法

    Bシェル内で変数をsedで編集しようとしているのですがうまくかないので教えてください。 変数SET_NO(=1.2.3-45)から.をとったものを変数EDIT_NOに入れようとしています。 ------------------------------------------------- SET_NO=1.2.3-45 #echo ${SET_NO} | sed -e "s/\.//g" #(0) #echo ${SET_NO} | sed -e "s/\.//g" | read EDIT_NO #(1) echo ${SET_NO} | sed -e "s/\.//g" > EDIT_NO #(2) read -u EDIT_NO #(3) echo "SET_NO=${SET_NO}" echo "EDIT_NO=${EDIT_NO}" ------------------------------------------------- (0)を有効にするとSET_NO=1.2.3-45となりsedはできています。 その結果を変数EDIT_NOに入れようとして(1)にしましたがEDIT_NOには何も入りませんでした。 (2)にしたら、EDIT_NOというファイルができてその中に入ってしまいました。そこで(3)を追加して読み込もうとしましたが read: EDIT_NO: invalid file descriptor specification となって読み込めません。 SET_NO 1.2.3-45から.をとったものをEDIT_NOに入れるにはどうすればいいのでしょうか。教えてください。よろしくお願いします。

  • シェルでコマンドの実行結果を変数に格納する方法

    以下のようなコマンドライン引数を取得するシェルを書いたのですが 実行時にエラーになってしまいました。コマンド(第2引数以降を取得するコマンド)の実行結果を変数に格納するところでエラーになってしまいました。どのようにすればよろしいでしょうか。 「./test2.sh a b c d e」を実行し「a: コマンドが見つかりません」 というエラーが出てしまいます。 (test2.shの内容) #!/bin/sh OUTPUTFILE=$1 SRC_FILES=`"$@" | cut -d ' ' -f 2-` # 第二引数以降を取得 echo $OUTPUTFILE ←ここは表示される echo $SRC_FILES ←ここでエラー

  • 【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]#

  • sedの置換文字に変数を使用したいのですが・・・

    あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。 例: X="a" Y="b" echo test.txt | sed 's/${X}/${Y/g}' >test.txt sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

  • コマンドの実行結果を変数に格納いしたい。

    有るプログラムへ特定ディレクトリのファイル数を渡す必要があり、バッチファイルを書いてますが、うまく行きません。 アドバイスを頂けましたら幸いです。 コマンドの実行欠課を変数に格納する方法を調べており、FOR文を使う事は分かったのですが、パイプを使った処理がうまく行きません。 ◎実行したいコマンド DIR /B | FIND /C /V "log” ◎バッチファイル @ECHO OFF for /f "usebackq tokens=*" %%i in (`DIR /B | FIND /C /V "log"`) do @set RESULT=%%i echo %RESULT% @ECHO ON パイプを使わず、単純なコマンドだと正常に変数に格納されますので、パイプでFINDに渡している事がだめだと思っております。 こういった場合、どう書けばよいかお教えください。

  • sedやperlでの2バイト文字を含む変換

    こんにちは。 sedコマンドは、texに付属していた日本語対応のものを使用しており、 perlはWindows用のActive Perl v.5.12.2を使用しています。 カレントディレクトリにあるファイルやフォルダにおいて、 名前を一括して変換したいと思い、以下のようなNameConv.batというバッチスクリプトを作成しました。 ____________________________________________________________ @echo off for /f "delims=" %%a in ('dir /b !opt!') do ( for /f "usebackq delims=" %%b in (`echo %%a^| sed -e "s/%~1/%~2/g"`) do ( move /y "%%a" "%%b" 1>nul 2>nul if not "%%a"=="%%b" echo 「%%a」→「%%b」 ) ) ____________________________________________________________ このバッチスクリプトを NameConv.bat " " "_" の様にして呼び出すと上手く行きました。 (この場合は、カレントディレクトリの全てのディレクトリとフォルダの名前において、 スペースがアンダーバーに変換されました。) ところが、 NameConv.bat "スペース" " " のように、第一引数に変換文字列に2バイト文字を使用すると、 以下のようなエラーメッセージが出て上手く行きませんでした。 sed: -e expression #1, char 14: Unterminated `s' command どうやら、 echo %%a| sed -e "s/スペース/ /g" といったコードは、上手く行かなかったようです。 そこで、この問題を解決しようと、以下のようなNameRep.plというPerlスクリプトを作成しました。 ____________________________________________________________ #日本語を扱うために必要な設定 use encoding "cp932"; use open ":encoding(cp932)"; use open ":std"; map{ binmode($_,":crlf"); } qw/STDIN STDOUT STDERR/; #置換操作 $name="$ARGV[0]"; $name =~ s/$ARGV[1]/$ARGV[2]/g; print "$name"; ____________________________________________________________ そしてこのスクリプトを for /f "delims=" %a in ('dir /b') do ( @perl NameRep.pl "%a" "スペース" "_" ) の様にしてコマンドラインから呼び出すことで、「スペース」という文字列が、 きちんと処理できるかを試したところ、以下のようなエラーメッセージが出ました。 Unmatched [ in regex; marked by <-- HERE in m/\x{00d8}\x{00f9}\x{005b} <-- HERE \x{00d8}/ at C:\Users\kei\NameRep.pl line 11. どうやら $name =~ s/$ARGV[1]/$ARGV[2]/g; の部分で、$nameや$ARGV[1]に2バイト文字が含まれていると、上手く行かないようです。 #日本語を扱うために必要な設定 以下のコードブロックで、シフトJISに対応できるはず(少なくとも今までは問題なく扱えました) なのですが、何故か上手く行きません。 そこで、sedコマンドやperl、特にperlにおいて、シフトJISコードでの2バイト文字の扱い方を御存じの方に、何かアドバイスを頂きたいと考えています。 長くなりましたが、どうぞよろしくお願い致します。

    • ベストアンサー
    • Perl
  • 【シェル】チルダの置換

    こんばんは。 Cシェルで1文字単位で置換する場合なのですが、 A→Y B→" C→3 D→~ のように対応しているファイルを読み込んで合致したらその文字に置換という方法にしています。その場合、D→~なので、ホームディレクトリが格納されてしまいます。 例えば、「ADC」という文字列があったら、「Y~3」というように置換したいのですが、「Y***/###3」のようになってしまいます。置換の際はechoとsedを使って、一度ファイルに落とし、それをまた変数に格納しています。 また、{や0もうまく読み込んでくれませんでした。クォーテーションでくくるとクォーテーションごと格納されました。("~" or '~') ファイルの方に\をつけて、\~でもうまくいきませんでした。 なんだか支離滅裂な文章ですが、ご存知の方いらっしゃいましたらどうぞ宜しくお願いします。

  • 変数格納  クォーテーション「あり」「なし」の違い

    変数格納する際、クォーテーション「あり」「なし」の違いはあるのでしょうか? ■質問背景 ・配列作成する際、クォーテーション「なし」でできたのに、取り出す際はクォーテーション付与しないとうまくいかなかった ・具体的には、"id" => '1', と変更したらうまくいった array(   0 => array     (       "id" => 1,       "city" => "tokyo"     ), ■質問 ・下記の違いは何でしょうか? ・文字列として格納するか数値として格納するかの違い? $hoge = 1; $hoge = '1'; $hoge = "1"; ・クォーテーションなしで変数に格納出来るのは数値だけ? $hoge = 文字列;

    • ベストアンサー
    • PHP