Linuxシェル文字列で%は何をしますか?


27

Linuxシェルでは、次のように%は何をしますか?

for file in *.png.jpg; do
  mv "$file" "${file%.png.jpg}.jpg"
done

4
これを調べるたびに、bashのmanページの適切なセクションを見つけるには、%%orまたは##を検索します。これは記憶に残り、適切なセクションをすばやく見つけるのに十分なほどまれだからです。 man bash /##
ピーターコーデス

3
@PeterCordes私はいつもこれを「5%だから、%は最後にあるので最後から切れている。そして#5だから、#は先頭にあり、先頭から切れる」と思い出します。しかし、時には私も...、この1をミックス
glglgl

2
@glglgl:典型的なUSAキーボードで#は、のすぐ左にあり$%すぐ右にあります。ニーモニックは必要ありません---ただ見下ろしてください。(おそらく、これらの記号が選択された理由の少なくとも一部です。)
ケビンJ.チェイス

@ KevinJ.Chase世界中の誰もが典型的なUSAキーボードを持っているわけではありません。しかし実際、ドイツ語のキーボードでは、%も$の権利であり、これはメモの開始点になる可能性があります。
glglgl

回答:


29

とき%のパターンで使用されている${variable%substring}、それはの内容を返しますvariableが、最短のoccuranceでsubstringの背中から削除しますvariable

この関数は、ワイルドカードパターンをサポートしています。そのため、スター(アスタリスク)をゼロ個以上の文字の代替として受け入れます。

これはBash固有であることに注意する必要があります-他のLinuxシェルには必ずしもこの関数が含まれていません。

Bashでの文字列操作の詳細については、このページを読むことを強くお勧めます。他の便利な機能の中で-例えば-何が何をするのか説明してい%%ます:)

編集:それがパターンで使用される$((variable%number))$((variable1%$variable2))%文字がモジュロ演算子として機能することを言及するのを忘れました。DavidPostillの回答には、より具体的なドキュメントリンクがあります。

%異なるコンテキストで使用される場合、通常の文字としてのみ認識される必要があります。


2
演算子は、正規表現ではなく、ワイルドカードパターンをサポートしています。
ガーデンヘッド

前述のgardenheadと同様に、正規表現ではなく、globパターンをサポートします。正規表現では、スターは前の文字のゼロ以上を意味します。
スリーブマン

5
あなたがリンクしたガイドはほとんどのUnix&Linuxスタック交換ユーザーにはあまりお勧めできません。代わりにWooledge Bash Guideをお勧めします。
ワイルドカード

3
接頭辞と接尾辞の削除演算子は標準であるため、shBashだけでなく、あらゆる互換性のあるシェルで使用できます。(おそらくないcshなど)。
-ilkkachu

1
%使用される別のコンテキストは、の形式指定子にありprintfます。
デニスウィリアムソン

9

Bashリファレンスマニュアル:シェルパラメーターの展開

${parameter%word}
${parameter%%word}

言葉は、単にファイル名展開の場合と同じようなパターンを生成するために拡張されます。パターンがparameterの展開値の末尾部分に一致する場合、展開の結果は、最短一致パターン(ケース)または最長一致パターン(ケース)が削除されたparameterの値になります。場合パラメータがあるか、パターン除去操作は順番に各位置パラメータに適用され、拡張は、結果のリストです。場合は、パラメータがで添字配列変数です か、‘%’‘%%’‘@’‘*’,‘@’‘*’, パターン削除操作は配列の各メンバーに順番に適用され、展開は結果のリストになります。


2
注意%を含むいくつかのパラメーター展開は、多くのシェルがサポートするposix機能です。
小次郎

7

実験により、文字列が中括弧(中括弧)で囲まれている場合、%の後の一致は破棄されることがわかりました。

説明する:

touch abcd         # Create file abcd

for file in ab*; do
 echo $file        # echoes the filename
 echo $file%       # echoes the filename plus "%"
 echo ${file%}     # echoes the filename
 echo "${file%}"   # echoes the filename
 echo
 echo "${file%c*}" # Discard anything after % matching c*
 echo "${file%*}"  # * is not greedy
 echo ${file%c*}   # Without quotes works too
 echo "${file%c}"  # No match after %, no effect
 echo $file%c*     # Without {} fails
done

出力は次のとおりです。

abcd
abcd%
abcd
abcd

ab
abcd
ab
abcd
abcd%c*

7

Linuxシェル(bash)では、何をし%ますか?

for file in *.png.jpg; do
  mv "$file" "${file%.png.jpg}.jpg"
done

この特定のケースでは、%あるパターンマッチング演算子(することもできることを注意モジュロ演算子)。


パターンマッチング演算子

$ {var%$ Pattern}、$ {var %% $ Pattern}

${var%$Pattern}のバックエンドに一致$varする最短部分から削除します。$Pattern$var

${var%%$Pattern}のバックエンドに一致$varする最長部分から削除します。$Pattern$var

例:パラメーター置換でのパターンマッチング

#!/bin/bash
# patt-matching.sh

# Pattern matching  using the # ## % %% parameter substitution operators.

var1=abcd12345abc6789
pattern1=a*c  # * (wild card) matches everything between a - c.

echo
echo "var1 = $var1"           # abcd12345abc6789
echo "var1 = ${var1}"         # abcd12345abc6789
                              # (alternate form)
echo "Number of characters in ${var1} = ${#var1}"
echo

echo "pattern1 = $pattern1"   # a*c  (everything between 'a' and 'c')
echo "--------------"
echo '${var1#$pattern1}  =' "${var1#$pattern1}"    #         d12345abc6789
# Shortest possible match, strips out first 3 characters  abcd12345abc6789
#                                     ^^^^^               |-|
echo '${var1##$pattern1} =' "${var1##$pattern1}"   #                  6789      
# Longest possible match, strips out first 12 characters  abcd12345abc6789
#                                    ^^^^^                |----------|

echo; echo; echo

pattern2=b*9            # everything between 'b' and '9'
echo "var1 = $var1"     # Still  abcd12345abc6789
echo
echo "pattern2 = $pattern2"
echo "--------------"
echo '${var1%pattern2}  =' "${var1%$pattern2}"     #     abcd12345a
# Shortest possible match, strips out last 6 characters  abcd12345abc6789
#                                     ^^^^                         |----|
echo '${var1%%pattern2} =' "${var1%%$pattern2}"    #     a
# Longest possible match, strips out last 12 characters  abcd12345abc6789
#                                    ^^^^                 |-------------|

# Remember, # and ## work from the left end (beginning) of string,
#           % and %% work from the right end.

echo

exit 0

ソースパラメータの置換


モジュロ演算子

%

モジュロ、またはmod(整数除算の剰余を返します)

bash$ expr 5 % 3
2

5/3 = 1、残り2

ソース演算子


たぶん私はそれを手に入れました:これは欲張りになりますが、欲張りになりますが、欲張りではない.*%定義しています%%か?だから、実際にリネーム例ではそれを使用するかどうかは関係ありません%か、%%それがなかった場合はmv "$file" "${file%.*png.jpg}.jpg"%%だけのためにすべてのファイルの名前を変更します使用して(*注).jpg、右?
トーマスウェラー

@ThomasWellerそれは正しいと思う。しかし、私はbashの専門家ではありません。
DavidPostill

「削除...の最短一部と言って$Pattern、」変数は次のように間違っている$Pattern例で定義されていないが、テキストのみ「パターン」から削除されている$var行っているとき${var%Pattern}${var%%Pattern}。たぶんこれは単なるタイプミスですが、それはtldp.orgが間違っている別の例です。BashGuideまたはBash Hackers Wikiは、どちらもはるかに優れたリファレンスです。
ジョンB

@JohnBありがとう。両方のリンクがブックマークされました。回答のテキストを修正しました。
DavidPostill
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.