プロが教えるわが家の防犯対策術!

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つの引数を渡すことができますでしょうか

A 回答 (4件)

別解を、ワンライナーで、


for f in *.{jpg,png,gif,bmp,jpeg};do echo ${f%.*} ${f#*.};done
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/03/08 10:05

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 じゃないとうまくいかない.
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/03/08 10:13

> system("bash ./echo.sh $name[0] $name[1]");



シェルスクリプトでの $1, $2, ... はコマンドラインの引数なので、上記の文はうまく行くのだと思います。パイプで渡した場合は、標準入力から読み取りなので read 等で処理する必要があるのでは、

$ cat echo.sh
IFS=.
while read name ext; do
echo $name $ext
done
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/03/08 10:03

こうではどうでしょうか。


http://pastebin.com/SihsLKk6
    • good
    • 0
この回答へのお礼

早々にお教え頂きありがとうございます。

期待していたのは、コマンドラインから1ライナーでパイプでつなげるやり方があるのかな・・・という思いでしたが、ご教授頂きありがとうございます。

なるほどですね~ 
変数に拡張子を登録しておいて
後から「変数に対するパターンマッチ」箇所で使うんですね。
今回の調べものの途中
http://www.atmarkit.co.jp/ait/articles/0202/05/n …
を読んでいて、ほうほう「変数に対するパターンマッチ」というのがあるんだぁ~なるほど~。と思っていた所、ちょうどタイムリーでした。

for file in *.${ext}箇所と${file%.${ext}}箇所の工夫が、また一歩上達の道を歩めました。

ありがとうございます。

お礼日時:2013/12/22 15:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!