Linux kabuk dizelerinde% ne yapar?


28

Linux kabuğunda,% 'in yaptığı gibi:

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

4
Bu kadar bakmak her zaman, genellikle arayarak bash adam sayfanın sağ bölümünü bulun %%veya ##bu hızla sağ bölümünü bulmak için unutulmaz ve nadir yeter beri. man bash /##
Peter Cordes

3
@PeterCordes Her zaman şunu hatırlıyorum: "% 5, yani% sonunda ve sonuçta kesiliyor. Ve # 5, yani # başında ve başında başlıyor". Ama bazen bunu karıştırdım bile…
glglgl

2
@glglgl: Tipik bir ABD klavyesinde, #hemen solundaki olduğunu $ve %hemen sağına. Anımsatmaya gerek yok --- sadece aşağı bak. (Muhtemelen en azından bu sembollerin seçilmesinin bir parçası.)
Kevin J. Chase

@ KevinJ.Chase Dünyadaki herkesin tipik bir ABD klavyesi yoktur. Ancak, aslında, Almanca bir klavyede,% 'nin de hakkıdır, bu hafızaya alma için bir başlangıç ​​olabilir.
glglgl 19.19

Yanıtlar:


29

Ne zaman %desende kullanılan ${variable%substring}bu içeriği dönecektir variablekısa çıkmasında ile substringarkasından silinir variable.

Bu işlev joker karakter kalıplarını destekler - bu yüzden yıldızı (yıldız) sıfır veya daha fazla karakter için alt alan olarak kabul eder.

Bunun Bash'e özgü olduğu söylenmelidir - diğer linux kabukları, bu işlevi gerektirmez bir şekilde içermez.

Bash'deki string manipülasyonu hakkında daha fazla bilgi edinmek istiyorsanız, bu sayfayı okumanızı tavsiye ederim . Diğer kullanışlı fonksiyonlar arasında - örneğin - ne %%yaptığını açıklıyor :)

Düzenleme: Ben desende kullanılan zaman belirtmeyi unutmuşum $((variable%number))ya karakter modülo operatörü olarak çalışacaktır. DavidPostill'in cevabında daha özel dokümantasyon bağlantıları var.$((variable1%$variable2))%

Ne zaman %farklı bir bağlamda kullanıldığında, düzenli karakteri sadece biri olarak kabul edilmelidir.


2
Operatör normal ifadeleri değil joker karakterlerini destekler .
gardenhead

Bahsedilen gardenhead'de olduğu gibi - normal ifadeleri değil normal ifadeleri destekler. Normal ifadede bir yıldız, önceki karakterin sıfır veya daha fazla anlamına gelir.
Slebetman

5
Bağlantı verdiğiniz Kılavuzu çok fazla değil tavsiye çoğu Unix & Linux yığın değişim kullanıcıları tarafından . Bunun yerine Wooledge Bash Kılavuzunu öneriyorum .
Wildcard

3
Ön ek ve son eki kaldırma işleçleri standarttır , bu nedenle shyalnızca Bash değil, tüm uyumlu kabuklarda kullanılabilir olmaları gerekir . (belki içinde cshve benzeri olmasa da ).
ilkkachu

1
İçinde %kullanıldığı bir başka içerik ise format belirticileridir printf.
sonraki duyuruya kadar duraklatıldı.

9

Bash Referans Kılavuzu: Kabuk Parametre Genişlemesi

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

Kelimesi sadece Dosyaismi gibi bir kalıp üretmek için genişletilir. Desen, genişletilmiş parametre değerinin izleyen bir kısmıyla eşleşirse, genişlemenin sonucu, en kısa eşleşen deseni ( durum) veya silinen en uzun eşleşen deseni ( durum) içeren parametrenin değeridir . Eğer parametresi olan ya da kalıp silme işlemi sırayla her parametre uygulanır ve sonuç bir listesidir. Eğer parametresi olan bir dizi değişken ile indisli veya‘%’‘%%’‘@’‘*’,‘@’‘*’, Desen kaldırma işlemi, dizinin her üyesine sırayla uygulanır ve genişleme, sonuç listesidir.


2
Not% dahil bazı parametre açılımları, birçok merminin desteklediği posix özellikleridir.
kojiro

7

Deneme yaparak, dize küme parantezlerine (kaşlı ayraçlar içine alındığında)% eşleşmeden sonra bir eşleşmenin atıldığını buldum.

Göstermek için:

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

İşte çıktı:

abcd
abcd%
abcd
abcd

ab
abcd
ab
abcd
abcd%c*

7

Linux kabuğunda ( bash) ne yapar %?

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

Bu özel durumda, %bir desen eşleştirme operatörü (aynı zamanda olabilir bunu unutmayın modülo operatörü).


Desen Eşleştirme Operatörü

$ {var% $ Desen}, $ {var %% $ Desen}

${var%$Pattern}Bunun arka ucuyla eşleşen $varen kısa bölümünden çıkarın .$Pattern$var

${var%%$Pattern}Bunun arka ucuyla eşleşen $varen uzun bölümünden çıkarın .$Pattern$var

Örnek: Parametre ikameinde model eşleştirme

#!/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

Kaynak Parametre Değiştirme


Modulo Operatörü

%

modulo veya mod (bir tamsayı bölme işleminin kalanını döndürür)

bash$ expr 5 % 3
2

5/3 = 1, kalan 2

Kaynak Operatörleri


Belki anladım: Bu gibi şeyler için ise .*ve %bunun oysa olmayan açgözlü olmak tanımlar %%yapar o açgözlü? Yani aslında yeniden adlandırma örnekte bunun önemi olmadığını kullanımına yapar %veya %%ancak olsaydı mv "$file" "${file%.*png.jpg}.jpg"sadece tüm dosyaları yeniden adlandırmak istiyorum %% kullanarak (* dikkat edin) .jpg, doğru mu?
Thomas Weller,

@ThomasWeller Ben doğru olduğunu düşünüyorum. Ama ben bir bash uzmanı değilim.
DavidPostill

$PatternDeğişken $Patternörnekte tanımlanmadığı için "Kaldır ... en kısa kısmı " demek yanlıştır , ya da sadece "Desen" metni veya $varyapıldığında kaldırılır . Belki bu sadece bir yazım hatası, ancak yine de tldp.org'un yanlış olmasının bir başka örneği. BashGuide veya Bash Hacker'lar Wiki'nin ikisi de çok daha iyi referanslar. ${var%Pattern}${var%%Pattern}
John B

@JohnB Teşekkürler. Her iki bağlantı da işaretlendi. Cevaptaki metni düzelttim.
DavidPostill
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.