スペースを含むデータに基づいてファイル名を動的に変更したいと思います。
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
が常に真になるということです。なぜなら 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
)が実行されるのを防ぎます。フィールド分割変数拡張後。