シェルスクリプトで複数の引数を渡す方法

このQ&Aのポイント
  • シェルスクリプトで複数の引数を渡す方法について質問しています。
  • 現在、ファイル名と拡張子の形で複数行からなる2つの引数を渡す方法を試していますが、うまくいっていません。
  • パイプ処理やファイル保存を試しましたが、引数が1つずつしか渡らない状況です。どのようにすれば複数の引数を渡せるでしょうか。
回答を見る
  • ベストアンサー

shellスクリプトに複数の引数を渡したい

shellスクリプトに複数の引数を渡したいと考えています。 下記のようなperlスクリプトを兼ねる事でやりたいことは達成できました。 これをシェルスクリプトだけでやろうとしていて、ハマってしまい、やり方がわからなかったので、質問しています。 ・echo.shの中身 $ cat echo.sh echo $1 $2 ・imglist.plの中身 $ cat imglist.pl my@imglist= `ls -1 *{.gif,.bmp,.jpg,.jpeg,.png} 2>1&`; foreach(@imglist){ my@name=split /\./,$_; system("bash ./echo.sh $name[0] $name[1]"); } ・実行すると、無事echo.shに引数が2つ渡る。 $ perl imglist.pl abc1 jpg abc10 png abc11 png abc2 jpg abc3 jpg これをシェルのみでやろうとして、はまってしまいました。 以下は、パイプ処理等を使ったりしてやってみたのですが出来ませんでした。 ・awkでファイル名と拡張子に分解し、パイプで渡そうとしても何故か渡らない・・ $ ls -1 *{.gif,.bmp,.jpg,.jpeg,.png} | awk -F . '{print $1,$2}'| bash ./echo.sh ・ファイルに一旦保存し、catコマンドでパイプで渡しても駄目 $ ls -1 *{.gif,.bmp,.jpg,.jpeg,.png} | awk -F . '{print $1,$2}' > imglist.txt $ cat imglist.txt | bash ./echo.sh ・echoコマンドを使ってパイプで渡しても駄目 $ echo `cat imglist.txt` |bash ./echo.sh ・for.shというファイルを作成し、for構文でimglist.txtの中身を渡すと引数が一つずつしか渡らない $ cat for.sh for id in $(cat imglist.txt); do echo $id done $ bash for.sh tile1 jpg tile10 jpg どうやれば、コマンドライン上やシェルスクリプトだけで、今回はファイル名と拡張子という形で複数行からなる2つの引数を渡すことができますでしょうか

  • taku0
  • お礼率80% (160/199)
  • Perl
  • 回答数4
  • ありがとう数17

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

  • ベストアンサー
回答No.3

別解を、ワンライナーで、 for f in *.{jpg,png,gif,bmp,jpeg};do echo ${f%.*} ${f#*.};done

taku0
質問者

お礼

ワンライナーで実現頂きありがとうございます。 変数に対するパターンマッチで、実現されてる辺り恐れ入ります。 ありがとうございます。

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

OS (というか find) によっては find . -maxdepth 1 -mindepth 1 -name '*{.gif,.bmp,.jpg,.jpeg,.png}' | sed -e 's=^./==; s/\./ /; s=^=bash ./echo.sh =' | bash のようにコマンドを組み立てる変態的な操作も可能. 最初の find は ls -1 *{.gif,.bmp,.jpg,.jpeg,.png} とだいたい同じなんだけど, たくさんファイルがある状況では find じゃないとうまくいかない.

taku0
質問者

お礼

おっしゃり通り変態的ですねw findの解説もさることながらsedの部分が変態すぎますw でも、参考になります。 ありがとうございます

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.2

> system("bash ./echo.sh $name[0] $name[1]"); シェルスクリプトでの $1, $2, ... はコマンドラインの引数なので、上記の文はうまく行くのだと思います。パイプで渡した場合は、標準入力から読み取りなので read 等で処理する必要があるのでは、 $ cat echo.sh IFS=. while read name ext; do echo $name $ext done

taku0
質問者

お礼

bashのreadは1行ずつ読むんですね。 ありがとうございます。

回答No.1

こうではどうでしょうか。 http://pastebin.com/SihsLKk6

taku0
質問者

お礼

早々にお教え頂きありがとうございます。 期待していたのは、コマンドラインから1ライナーでパイプでつなげるやり方があるのかな・・・という思いでしたが、ご教授頂きありがとうございます。 なるほどですね~  変数に拡張子を登録しておいて 後から「変数に対するパターンマッチ」箇所で使うんですね。 今回の調べものの途中 http://www.atmarkit.co.jp/ait/articles/0202/05/news001.html を読んでいて、ほうほう「変数に対するパターンマッチ」というのがあるんだぁ~なるほど~。と思っていた所、ちょうどタイムリーでした。 for file in *.${ext}箇所と${file%.${ext}}箇所の工夫が、また一歩上達の道を歩めました。 ありがとうございます。

関連するQ&A

  • シェルスクリプト 引数の引渡しについて

    こんにちは。現在シェルスクリプトを勉強中なのですがどうしてもわからないことがあり投稿させていただきました。 シェルスクリプトにて作成した引数(引数にスペースがある場合)を別のシェルスクリプトへ渡そうとしたときにうまく引き渡せなくて困っています。 詳しくは以下のスクリプト参照願います。 (1)引数作成のスクリプト _/_/_/_/_/_/_/_/_/_/_/_/ #!/bin/sh a="HELLO" b="\"WOW WOW\"" test.sh $a $b _/_/_/_/_/_/_/_/_/_/_/_/ (2)test.sh _/_/_/_/_/_/_/_/_/_/_/_/ #!/bin/sh echo $1 echo $2 echo $3 _/_/_/_/_/_/_/_/_/_/_/_/ これを実行すると $1=HELLO $2="WOW $3=WOW" となってしまいます。 これを $1=HELLO $2=WOW WOW $3=NULL(空欄) となるようにシェルスクリプトで作成することはできないのでしょうか? ご教授よろしくお願いします。 よろしくお願いします。

  • shellスクリプトから別のshellスクリプトを呼び出す方法

    今現在VineLinux4.1をサーバとして起動させております。 その関係もありまして維持としてシェルを動かす事はある意味必須の状態です。 本題はAと言うスクリプトからBと言うスクリプトを呼び出す方法がわかりません。 試してみた方法はsourceで呼び出す方法です。 A.shの中身を以下とすると #!bin/bash echo ="B.shを呼び出します" source B.sh echo ="シェルスクリプトを終了します" exit 0 上記のようにした場合、最初のecho文は出力され、B.shの内容を一通り終えると最後のechoは出力されずA.shは完了しません。 ごくごく基本的なことかもしれませんが、うまく検索にも引っ掛けられなかったので、ご質問させていただきます。 よろしくお願い致します。

  • shellスクリプトで引数をhashとして展開させ

    お世話になります。 シェルスクリプトで引数をハッシュの文字列として展開できないかな・・と思考錯誤しています。 . ./test.sh abc #!/bin/bash declare -A abc # -Aでハッシュ宣言 abc["0"]="0" abc["1"]="1" abc["2"]="2" abc["3"]="3" abc["4"]="4" abc["5"]="5" abc["6"]="6" abc["7"]="7" abc["8"]="8" abc["9"]="9" abc["10"]="10" declare -A xyz # -Aでハッシュ宣言 xyz["0"]="0" xyz["1"]="1" xyz["2"]="2" xyz["3"]="3" xyz["4"]="4" xyz["5"]="5" xyz["6"]="6" xyz["7"]="7" xyz["8"]="8" xyz["9"]="9" xyz["10"]="10" declare -A zzz # -Aでハッシュ宣言 zzz["0"]="0" zzz["1"]="1" zzz["2"]="2" zzz["3"]="3" zzz["4"]="4" zzz["5"]="5" zzz["6"]="6" zzz["7"]="7" zzz["8"]="8" zzz["9"]="9" zzz["10"]="10" if [ "$1" = "abc" ]; then echo "$1:${abc[$(( ${RANDOM} * 11 / 32768 ))]}" elif [ "$1" = "xyz" ]; then echo "$1:${xyz[$(( ${RANDOM} * 11 / 32768 ))]}" else echo "$1:${zzz[$(( ${RANDOM} * 11 / 32768 ))]}" fi もしハッシュが増える場合、elifの部分を沢山書いていくのではなく、 下記のような形にすっきりさせたいと思っているのですが、$1の値をハッシュとして展開させるやり方がわかりません。 if [ "$1" ]; then #ここの部分で$1をハッシュとして展開させる為の記述方法がわかりません。 #下記のいずれも「: 誤った代入です」となってしまいます echo "$1:${$${1}[$(( ${RANDOM} * 11 / 32768 ))]}" echo "$1:${${1}[$(( ${RANDOM} * 11 / 32768 ))]}" echo "$1:${${1[$(( ${RANDOM} * 11 / 32768 ))]}}" echo "$1:${$1[$(( ${RANDOM} * 11 / 32768 ))]}" else echo "$1:${zzz[$(( ${RANDOM} * 11 / 32768 ))]}" fi どなた様か、ご教授願えませんでしょうか。よろしくお願いしたします。

  • awkコマンドに引数を渡す方法

    awkコマンドに対して引数を渡す方法が知りたいです。 例えば以下のようなリストファイルがあったとします。 --------------------------------------- % cat test.lst 454 100 37536 200 32432 300 34q2 400 --------------------------------------- そこで以下のシェルを実行すると --------------------------------------- #!/bin/sh for VAL in 100 200 300 do CNT=`cat test.lst | awk '$2 == $VAL {print $1}'` echo "$VAL : $CNT" done --------------------------------------- awkコマンド内の$VALが引数ではなく文字列として認識されてしまうため、 出力結果が 100 : 200 : 300 : となってしまいます。 100 : 454 200 : 37536 300 : 32432 という結果を出力したい場合(awk内の引数を有効にする場合)どうすればよいでしょうか? awkを使用しない方法もあるかと思いますが、今回はawkを使った方法を知りたいです。 宜しくお願い致します。

  • shのシェルスクリプトの演算方法について・・・

    bashのシェルスクリプトについてもお聞きしたのですが、 その方法では演算ができない!ということになってしまいました・・・ こういうちょこっとしたところが違うのが嫌です・・・↓ bashの場合は ---------- bash$ a=1 bash$ a=$(( $a + 1 )) bash$ echo $a 2 ---------- となったのですが、shではエラーが出てしまいました・・・ また、shのスクリプトもbashのスクリプトもシェルスクリプトと呼ぶのでしょうか?

  • 簡単なシェルスクリプトを見てください。

    次のようなシェルスクリプトを作成しました。 #!/bin/sh echo [$1] awk '/"0312345678"/ {print}' /test > /test1 awk '/$1/ {print}' /test > /test2 のように簡単なスクリプトです。 $ sample \"0312345678\" で実行させたら、echo では"0312345678"に出力されます。 しかし、test1にはちゃんと結果が入っていますが、test2は空のファイルです。 なぜ、結果が違うのですか? 実行時、引数を渡す方法で、test1と同じ結果を得たければ、どうすればいいのですか?

  • linuxのシェルスクリプト

    linuxのシェルスクリプト シェルスクリプトの質問をどこですればよいのかよくわからないので、ここでさせていただきます。 最近、始めてシェルスクリプトの勉強を始めました。 スクリプトに渡す引数を出力したいと思い、 echo $1 echo $2 echo $3 とかくと、スクリプトに渡した引数が出力されます。 これを、for文で書くと for i in 1 2 3 do echo $i done とねるのですが、これでは1,2,3が出力されてしまいます。 どうなおしたらいいのでしょうか? よろしくお願いいたします。

  • シェルスクリプトの引数について

    test.sh '*.c' といったコマンドを入力した時に、 シェルスクリプト内で引数$1を受け取ったときに$1='*.c'となるのではなく、 カレントディレクトリ内にある'*.c'の正規表現にマッチするファイルが入ってしまっています。 例)カレントディレクト内にaaa.cファイルbbb.cファイルといったファイルがある時は、 $1=aaa.c bbb.cとなっています。 '*.c'の正規表現自体をシェルスクリプト内で受け取る方法はないのでしょうか? シェルはbashを使用しています。

  • シェルの引数チェックについて

    HP-UNIX シェルで指定された引数の桁数のチェックや入力値のチェックを 行いたいと思っております。 自分なりに調べた所、awkコマンドを使用して、lengthや正規表現 でチェックできそうなのですが、シェルで指定された引数をどの ようにしてチェックすればよいのかがわかりません。 例)aaa.sh 引数1 引数2   ⇒aaa.shの中で、$@等で上記のチェックを行う???  イメージとしては、   ・if (length($1) == 10) ・$1!~/[a-zA-Z0-9]/  でも、aaa.shの中で、awkの使用方法がわかりません。 awkを使用する以上、ls -l | awk ~~~ のように、 一度、引数をファイルに出力してから、grepとパイプ機能を使用 する?しか方法はないでしょうか。 (実行環境で、パーミッションの設定でシェルを実行できない 為、上記の方法を試すには到っていません・・・パーミッションについて も、まだ理解が乏しい為。) シェルスクリプトを触り出して、まだ間もない事もあり、可能な のかどうかも判断できない状況ですが、ご存知の方がいらっしゃ いましたら、ご教授頂ければと思います。  

  • 【継続質問】シェルスクリプトを用いて、ある特定の文字列の前に文字列を挿入

    シェルスクリプトを用いて、ある特定の文字列の前に文字列を挿入 の継続質問です。よろしくお願いします。 tacとawkを用いて、"ある特定の文字列の前に文字列を挿入"ということができるのは、 確認することができました。 例えば、  script.awk (awkスクリプト)  sample.txt (処理対象ファイル) という環境で、  $ cat script.awk  $ tac sample.txt | awk -f script.awk | tac > sample2.txt とコマンドを入力した場合、 sample2.txtに、処理が完了したテキストが作成され、 中身も問題ないことを確認できました。 しかし以下のようなことを実現しようと思うと、 うまく行きませんでした・ 「非対話的に上記の処理を行いたいのです」 上記の方法では、 catとtacと2回コマンドを叩く必要があります (1回にもできるのでしょうが…) できれば、自動的に流れる膨大なシェルスクリプトの処理の中で、 上記の処理を自動的に行うということを実現したいのです。 例えば、auto.shというシェルを実行すれば、 勝手にawkスクリプトを読み込み、勝手に変換したものを出力してくれる… そのようなシェルを作成したいと考えています。 そこで色々試しましたが上手くいきません。 1.コマンドの分解ができない tac sample.txt | awk -f script.awk | tac > sample2.txt の上記を、  #!/bin/sh  tac sample.txt  awk -f script.awk  tac > sample2.txt のようにシェルスクリプトに記述しなおして実行しましたが、 上手くいきませんでした。 2.script.awk(awkスクリプト)を内部に取り込み 外部ファイルとして存在している、script.awkをなんとか シェルに組み込もうと思って、  awk {(script.awkの内容をそのまま記述)} のように行いましたが、文法的にやはり無茶苦茶でした・・・。 正直、2番が無理であれば仕方ありませんが、 最低でも1は実現したいと思います。 1の方法だけでも良いので、どなたか回答をお願いします。