공백이 포함된 파일의 이름을 동적으로 바꿉니다.

공백이 포함된 파일의 이름을 동적으로 바꿉니다.

공백이 포함된 데이터를 기반으로 파일 이름을 동적으로 바꾸고 싶습니다.

Name="Abc DEF"
Name1="GHI JKL"

mv /sample/pdf/noriginalName.pdf /sample/outputPdf/${NAME}${Name1}".pdf"

하지만 그 사이에 공백이 있어서 오류가 발생했습니다.

어떻게 해야 하나요?

답변1

걱정하지 마세요. 당신이 물린 첫 번째도, 마지막도 아닐 것입니다. 이는 쉘에 관한 가장 일반적인 질문이며 쉘 스크립트에서 발견되는 대부분의 버그 및 보안 취약점의 원인입니다. 이는 Unix 역사 초기에 Bourne 쉘과 Korn 쉘의 잘못된 디자인 선택 때문입니다.

Bourne 셸과 대부분의 하위 항목(ksh, ash, pdksh, mksh, bash, dash, yash...)에서 변수를 인용 해제하는 것은 Split+glob 연산자입니다.

가장 좋은 증거는 다음과 같습니다.

$ var='*.txt,.*'
$ IFS=',' # default is space tab and newline
$ printf '<%s>\n' $var
<file.txt>
<.>
<..>

쉘은 문자 $var별로 분할되었으며 , 각 결과 단어는 해당 패턴과 일치하는 파일 목록에서 확장되었습니다(이 경우 와일드카드 포함).

이것이 바로 Bourne과 같은 쉘( 제외 zsh) 에서~ 해야 하다항상 변수를 인용하십시오(정말로 원하지 않는 한).나뉘다그리고/또는전반적인 상황)

$ printf '<%s>\n' "$var"
<*.txt:.*>

귀하의 경우에는 다음과 같습니다.

mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"

또는:

mv /sample/pdf/noriginalName.pdf /sample/outputPdf/"${NAME}${Name1}".pdf

(변수가 인용되어 있는 한 인용문의 위치는 중요하지 않습니다.)

다음 방법으로만 분할을 비활성화할 수 있습니다.

IFS=

다음과 같은 방법으로만 와일드카드를 비활성화할 수 있습니다.

set -f # affects all globbing, not only the one done upon variable expansion.

그리고:

IFS=; set -f

매개변수 확장과 동일한 동작을 가지며 zsh와일드카드도 없고 분할도 없습니다. 하지만 여전히 변수를 참조해야 합니다.

cmd "$var"

cmd합격하고 싶다면하나비어 있거나 설정되지 않은 경우 빈 매개변수 $var(와 동일)아니요전혀 논쟁이 없습니다.) 일반적인 예는 을 [ -n "$var" ]인용하지 않으면 $var테스트가 항상 true가 된다는 것입니다. 왜냐하면 null인 경우 대신 $var으로 확인되기 때문입니다 .[ -n ][ -n '' ]

에서는 변수 확장 시 와일드카드 지정 및 분할이 암시적으로 수행되지 않습니다( 또는 에뮬레이션 모드 zsh제외 ). 특정 스프레드 연산자( 토큰화, 와일드카드(또는 둘 다))를 사용하여 명시적으로 요청해야 합니다.shksh$=var$~var${~var}$~=var

이 문제가 없는 다른 쉘은 fish, 및 rc해당 하위 쉘( es, akanga)입니다.

존재하다 (t)csh:

cmd "$var"

$var도움이 되지만 개행 문자가 포함되면 작동하지 않기 때문에 충분하지 않습니다. 다음이 필요합니다.

cmd $var:q

답변2

전체 파일 이름을 인용해야 합니다.

mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"

큰따옴표를 사용하면 bashBourne과 유사한 다른 쉘( 제외 zsh)이 실행되는 것을 방지할 수 있습니다.필드 분할변수 확장 후.

관련 정보