dポイントプレゼントキャンペーン実施中!

#!/bin/zsh
file1="dog.jpg cat.mpg"
echo ${file1/.*/.png}
echo ${file1//.*/.png}

を実行すると、両方とも
dog.png
になってしまうのですが、
最後の文字列置換は、
dog. png cat.png
になるように思うのですが、何故そうならないのでしょうか?

質問者からの補足コメント

  • ひとつ教えて下さい。

    echo ${file1//.[^ ]##/.png}
    で、
    .[^ ]の後の##は何を意味するのでしょうか?
    変数名とパターンの区切り文字の##なのでしょうか?
    それって、変数の文字列置換機能の
    ${変数//検索文字列/置換文字列}
    の書式と一緒に使えるのでしょうか?

    No.2の回答に寄せられた補足コメントです。 補足日時:2023/07/25 12:53
  • 理解が悪くて申し訳ないですが、
    確認なのですが、
    .[^ ]##
    は、${変数名##パターン}の変数展開機能で、
    変数名が.[^ ]で、パターンが無いという理解で良いのでしょうか?

    No.3の回答に寄せられた補足コメントです。 補足日時:2023/07/26 00:21
  • 正規表現で、#の使い方を検索してもそれらしい使い方が見つからないので質問しているのですが、
    ## は「1回以上の繰り返し」
    という意味になるのでしょうか?

    No.4の回答に寄せられた補足コメントです。 補足日時:2023/07/26 07:51

A 回答 (5件)

> 正規表現で、#の使い方を検索してもそれらしい使い方が見つからないので質問しているのですが、



今回は正規表現は全く関係ないです。
${変数//検索文字列/置換文字列}
の検索文字列の部分に書くのは正規表現じゃないです。

もし正規表現だとすると、質問文にお書きの、echo ${file1/.*/.png} だと、.* で文字列全体にマッチするのですが、それを意図して書いたわけでは無いですよね?
「ピリオドの後に任意の文字列」という意図だったのでは?それは正規表現じゃ無いです。

Zshのマニュアルだと、${name//pattern/repl} と書いてありますが、その前の部分で、pattern とは filename generation と同じと書いてあります(the same as that used for filename generation)。日本語版のあるBashのマニュアルだと同じ物が「パス名展開」となっていますが、こちらの方が分かり易いか。多くのサイトで「ワイルドカード」とか「ファイルマッチ」と書いてあったりします。ls -l *.jpg とか書くときの * の機能のことですね。

* が0文字以上の任意の文字列(正規表現の .* と同じ)
? が1文字の任意の文字(正規表現の . と同じ)
[ ] は正規表現とほぼ同じ
など。. は単なる普通の文字です。
man zshexpn の FILENAME GENERATION の節に一覧があり、そこに ## も載っています。
最初の Tacosan さんの回答に、man zshexpn のウェブ上のURLがあります。
    • good
    • 0
この回答へのお礼

14.8.1 Glob Operators
に記載がありました。探しきれてなかったので、正規表現にあるのかと
勘違いしていました。ありがとうございます。

お礼日時:2023/08/02 15:30

> .[^ ]##は、${変数名##パターン}の変数展開機能で、変数名が.[^ ]で、パターンが無いという理解で良いのでしょうか?



全く違います。
「${変数名##パターン}」と「.[^ ]##」は、全く似てないですが、これが同じに見えるのでしょうか???

> > ${変数//検索文字列/置換文字列} の書式と一緒に使えるのでしょうか?
>
> ${file1//.[^ ]##/.png}
> は、まさにその書式ですけど???

とい文章が理解してもらえないとすると、お手上げです。

${変数//検索文字列/置換文字列} の書式の、
変数:file1
検索文字列:.[^ ]##
置換文字列:.png
なのですが。
この回答への補足あり
    • good
    • 0

「ピリオドの後に、空白以外の文字が1文字以上続く」が


.[^ ]##
に該当するという意味が通じなかったと言うことですか?
と思ったら、

> それって、変数の文字列置換機能の ${変数//検索文字列/置換文字列} の書式と一緒に使えるのでしょうか?

???
${file1//.[^ ]##/.png}
は、まさにその書式ですけど???

${file1//.[^ ]##/.png} が ${変数//検索文字列/置換文字列} に見えないとは思いもしなかったので、その旨もわざわざ書きませんでした。

「ピリオドの後に、空白以外の文字が1文字以上続く」が
.[^ ]##
に該当すると検索文字列だという意味が通じている前提だと、## は「1回以上の繰り返し」だとわかりますよね?javascript:void 0;
この回答への補足あり
    • good
    • 0

.* は「ピリオドの後に任意の文字列(空白でも何でも)」なので、


"dog.jpg cat.mpg" に対しては、".jpg cat.mpg"にマッチします。
その後ろに .* にマッチする文字列は無いので、/ でも // でも同じです。

拡張子が英小字3文字限定なら
echo ${file1//.[a-z][a-z][a-z]/.png}

「ピリオドの後に、空白以外の文字が1文字以上続く」だと、拡張オプションをセットして、
setopt EXTENDED_GLOB
echo ${file1//.[^ ]##/.png}
この回答への補足あり
    • good
    • 0

マニュアルを読んでから質問することを


強く
お薦めする
https://zsh.sourceforge.io/Doc/Release/Expansion …
    • good
    • 0

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