공백이 포함된 데이터를 기반으로 파일 이름을 동적으로 바꾸고 싶습니다.
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
제외 ). 특정 스프레드 연산자( 토큰화, 와일드카드(또는 둘 다))를 사용하여 명시적으로 요청해야 합니다.sh
ksh
$=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"
큰따옴표를 사용하면 bash
Bourne과 유사한 다른 쉘( 제외 zsh
)이 실행되는 것을 방지할 수 있습니다.필드 분할변수 확장 후.