리눅스 쉘 문자열에서 %는 무엇을 하는가?


28

Linux 쉘에서 %는 다음과 같이 무엇을합니까?

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

4
내가 이것을 찾을 때마다 나는 보통 bash 맨 페이지의 올바른 섹션을 찾 %%거나 또는를 검색 ##하여 올바른 섹션을 빨리 찾을 수있을 정도로 기억하기 어렵습니다. man bash /##
Peter Cordes

3
@PeterCordes는 항상 "5 %이므로 %는 끝이어서 끝에서 삭감됩니다. 그리고 # 5이므로 시작이되며 시작부터 삭감됩니다." 하지만 때로는 이걸 섞기도합니다.
glglgl

2
@glglgl : 일반적인 미국 키보드에서 #바로 왼쪽에 $있고 %바로 오른쪽에 있습니다. 니모닉이 필요하지 않습니다. (이것은 아마도 그 기호가 선택된 이유의 적어도 일부일 것입니다.)
Kevin J. Chase

@ KevinJ.Chase 전 세계의 모든 사람이 전형적인 미국 키보드를 가지고있는 것은 아닙니다. 그러나 실제로 독일어 키보드에서 %도 $의 권리입니다.
glglgl

답변:


29

%패턴으로 사용 되면의 뒤로 삭제 된 항목 이 가장 짧은 ${variable%substring}내용을 반환합니다 .variablesubstringvariable

이 함수는 와일드 카드 패턴을 지원하므로 별 (별표)을 0 개 이상의 문자에 대한 대체 문자로 허용합니다.

이것은 Bash와 관련이 있으며 다른 Linux 쉘에는이 기능이 필요하지 않습니다.

Bash에서 문자열 조작에 대해 더 배우고 싶다면 읽는 것이 좋습니다. 페이지를 . 다른 편리한 기능 중-예를 들어- %%수행하는 작업을 설명합니다 :)

편집 : 패턴으로 사용될 때 언급하는 것을 잊었습니다. $((variable%number)) 또는 문자가 나머지 연산자의 기능을합니다. DavidPostill은 그의 답변에보다 구체적인 문서 링크를 가지고 있습니다.$((variable1%$variable2))%

%다른 상황에서 사용될 때는 일반 문자로만 인식해야합니다.


2
연산자는 정규식이 아닌 와일드 카드 패턴을 지원합니다 .
gardenhead

가든 헤드가 언급 한 것처럼 정규 표현식이 아닌 글로브 패턴을 지원합니다. 정규식에서 별표는 이전 문자 중 0 개 이상을 의미합니다.
slebetman

5
링크 된 가이드는 대부분의 Unix & Linux 스택 교환 사용자에게 권장 되지 않습니다 . 대신 Wooledge Bash Guide 를 권장합니다 .
와일드 카드

3
접두사 및 접미사 제거 연산자는 표준 이므로 shBash뿐만 아니라 호환 되는 모든 쉘 에서 사용할 수 있어야합니다 . (아마도 그렇지는 않지만 csh).
ilkkachu

1
%사용되는 또 다른 컨텍스트 는에 대한 형식 지정자입니다 printf.
추후 공지가있을 때까지 일시 중지되었습니다.

9

Bash 참조 매뉴얼 : Shell Parameter Expansion

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

단어는 단지 파일 이름 확장에서 같은 패턴을 생성하기 위해 확장된다. 패턴이 확장 된 parameter 값의 후행 부분과 일치하면 확장 결과는 일치하는 가장 짧은 일치 패턴 ( 경우) 또는 삭제 된 가장 긴 일치 패턴 (경우)을 가진 parameter 의 값입니다 . 경우 파라미터 이다 또는 패턴 제거 동작이 차례로 각 위치 파라미터에인가되고, 팽창 얻어진리스트이다. parameter 가 or로 첨자 된 배열 변수 인 경우‘%’‘%%’‘@’‘*’,‘@’‘*’, 패턴 제거 작업이 배열의 각 멤버에 차례로 적용되고 확장이 결과 목록입니다.


2
NB %를 포함한 일부 매개 변수 확장은 많은 쉘이 지원하는 posix 기능입니다.
kojiro

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, 맞죠?
Thomas Weller

@ThomasWeller 나는 그것이 맞다고 생각합니다. 그러나 나는 배쉬 전문가가 아니다.
DavidPostill

예제에서 $Pattern변수 $Pattern가 정의되지 않았기 때문에 "Remove ... the shortest of the shortest "는 잘못되었습니다 . 또는 " $var를 수행 할 때 "Pattern "텍스트 만 제거됩니다 . 어쩌면 이것은 오타 일 수도 있지만 tldp.org의 또 다른 예입니다. BashGuide 또는 Bash Hackers Wiki 는 모두 imho를 훨씬 잘 참조합니다. ${var%Pattern}${var%%Pattern}
John B

@JohnB 감사합니다. 두 링크 모두 북마크되었습니다. 답변의 텍스트를 수정했습니다.
DavidPostill
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.