Apa yang dilakukan% dalam string shell Linux?


28

Di Linux shell, apa yang dilakukan%, seperti pada:

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

4
Setiap kali saya mencari ini, saya biasanya menemukan bagian kanan halaman bash man dengan mencari %%atau ##, karena itu cukup mudah diingat dan langka untuk menemukan bagian yang tepat dengan cepat. man bash /##
Peter Cordes

3
@PeterCordes Saya selalu ingat ini dengan "Ini 5%, jadi% di akhir dan dengan demikian memotong dari akhir. Dan itu # 5, jadi # di awal dan memotong dari awal." Tetapi kadang-kadang saya bahkan mencampuradukkan yang ini ...
glglgl

2
@glglgl: Pada papan ketik khas Amerika Serikat, #langsung ke kiri $, dan %langsung ke kanan. Tidak perlu mnemonik --- lihat saja ke bawah. (Itu mungkin setidaknya bagian dari mengapa simbol-simbol itu dipilih.)
Kevin J. Chase

@ KevinJ.Chase Tidak semua orang di seluruh dunia memiliki keyboard khas Amerika Serikat. Tapi tentu saja, pada keyboard Jerman,% benar $ juga, itu bisa menjadi awal untuk memoizing.
glglgl

Jawaban:


29

Ketika %digunakan dalam pola ${variable%substring}itu akan mengembalikan konten variabledengan kejadian terpendek substringdihapus dari belakang variable.

Fungsi ini mendukung pola wildcard - itulah sebabnya ia menerima bintang (tanda bintang) sebagai subtitle untuk nol atau lebih karakter.

Harus disebutkan bahwa ini khusus untuk Bash - shell linux lain tidak perlu mengandung fungsi ini.

Jika Anda ingin mempelajari lebih lanjut tentang manipulasi string di Bash, saya sangat menyarankan membaca halaman ini . Di antara fungsi praktis lainnya - misalnya - menjelaskan apa yang %%harus dilakukan :)

Edit: Saya lupa menyebutkan bahwa ketika itu digunakan dalam pola $((variable%number))atau $((variable1%$variable2))yang %karakter akan berfungsi sebagai operator modulo. DavidPostill memiliki tautan dokumentasi yang lebih spesifik dalam jawabannya.

Ketika %digunakan dalam konteks yang berbeda, itu harus dikenali sebagai karakter biasa saja.


2
Operator mendukung pola wildcard , bukan ekspresi reguler.
gardenhead

Seperti gardenhead yang disebutkan - mendukung pola glob, bukan ekspresi reguler. Dalam ekspresi reguler, bintang berarti nol atau lebih dari karakter sebelumnya.
slebetman

5
Panduan yang Anda tautkan sangat tidak direkomendasikan oleh sebagian besar pengguna pertukaran pertukaran Unix & Linux . Saya merekomendasikan Woolash Bash Guide sebagai gantinya.
Wildcard

3
Awalan dan akhiran menghapus operator adalah standar , sehingga mereka harus dapat digunakan dalam shshell yang kompatibel, tidak hanya Bash. (Meskipun mungkin tidak dalam cshdan sejenisnya).
ilkkachu

1
Konteks lain yang %digunakan adalah penentu format untuk printf.
Dijeda sampai pemberitahuan lebih lanjut.

9

Manual Referensi Bash: Ekspansi Parameter Shell

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

The Kata diperluas untuk menghasilkan pola seperti dalam ekspansi nama file. Jika pola cocok dengan bagian tambahan dari nilai parameter yang diperluas , maka hasil ekspansi adalah nilai parameter dengan pola pencocokan terpendek ( ‘%’kasing) atau pola pencocokan terpanjang ( ‘%%’kasing) dihapus. Jika parameter adalah ‘@’atau ‘*’,operasi penghapusan pola diterapkan untuk setiap parameter posisional pada gilirannya, dan ekspansi adalah daftar yang dihasilkan. Jika parameter adalah variabel array yang disubkripsikan dengan ‘@’ atau‘*’, operasi penghapusan pola diterapkan pada setiap anggota array secara bergantian, dan ekspansi adalah daftar yang dihasilkan.


2
NB beberapa perluasan parameter termasuk% adalah fitur posix yang didukung banyak shell.
kojiro

7

Dengan bereksperimen, saya menemukan bahwa kecocokan setelah% dibuang, ketika string tertutup dalam kurung keriting (kurung kurawal).

Menggambarkan:

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

Berikut hasilnya:

abcd
abcd%
abcd
abcd

ab
abcd
ab
abcd
abcd%c*

7

Di Linux shell ( bash), apa fungsinya %?

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

Dalam kasus ini, %adalah pencocokan pola operator (perhatikan juga bisa menjadi modulo operator).


Operator Pencocokan Pola

$ {var% $ Pattern}, $ {var %% $ Pattern}

${var%$Pattern}Hapus dari $varbagian terpendek $Patternyang cocok dengan bagian belakang $var.

${var%%$Pattern}Hapus dari $varbagian terpanjang $Patternyang cocok dengan bagian belakang $var.

Contoh: Pencocokan pola dalam substitusi parameter

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

Substitusi Parameter Sumber


Operator Modulo

%

modulo, atau mod (mengembalikan sisa operasi pembagian integer)

bash$ expr 5 % 3
2

5/3 = 1, dengan sisanya 2

Operator Sumber


Mungkin saya mengerti: ini untuk hal-hal seperti .*dan %mendefinisikannya sebagai tidak serakah sedangkan %%membuatnya serakah? Jadi sebenarnya dalam contoh ganti nama itu tidak masalah apakah akan menggunakan %atau %%tetapi jika mv "$file" "${file%.*png.jpg}.jpg"(perhatikan *) menggunakan %% akan mengubah nama semua file menjadi adil .jpg, kan?
Thomas Weller

@ ThomasWeller saya pikir itu benar. Tapi aku bukan ahli bash.
DavidPostill

Mengatakan "Hapus ... bagian terpendek dari $Pattern" salah karena variabel $Patterntidak didefinisikan dalam contoh, hanya teks "Pola" yang dihapus dari $varsaat melakukan ${var%Pattern}atau ${var%%Pattern}. Mungkin ini hanya salah ketik, tapi ini contoh lain kesalahan tldp.org. BashGuide atau Bash Hackers Wiki keduanya adalah referensi yang jauh lebih baik.
John B

@ JohnB Terima kasih. Kedua tautan itu ditandai. Saya sudah mengoreksi teks dalam jawaban.
DavidPostill
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.