次の例では、この問題について説明します。FILENAME
交換を使用すると、エコーが正しく印刷され、パターンとして認識されるのはなぜですか?
#!/bin/bash
FILEPATH_WITH_GLOB="/home/user/file_*"
FILENAME=$(basename "$FILEPATH_WITH_GLOB")
echo $FILENAME #file_1234
echo ${FILENAME:1:5} #ile_* <---why is this not ile_1
ベストアンサー1
FILEPATH_WITH_GLOB="/home/user/file_*"
これで、次のFILEPATH_WITH_GLOB
ものが含まれます。/home/user/file_*
FILENAME=$(basename "$FILEPATH_WITH_GLOB")
FILENAME
含むfile_*
。
echo $FILENAME #file_1234
$FILENAME
リストコンテキストに引用符がない場合、拡張は分割+グローブ演算子を介して進行するため、一致するファイルのリストに展開されます。ファイル名の生成に実行パラメータ拡張。
echo ${FILENAME:1:5} #ile_* <---why is this not ile_1
リストコンテキストではまだ引用符がない引数拡張なので、まだ分割+globを経ます。しかし、ここではile_*
パターンがどのファイルとも一致しないので、パターン自体に拡張されます。
おそらくあなたが望むものは次のとおりです。
shopt -s nullglob # have globs expand to nothing when they don't match
set -- /home/user/file_* # expand that pattern into the list of matching
# files in $1, $2...
for file do # loop over them
filename=$(basename -- "$file")
printf '%s\n' "$filename" "${filename:1:5}"
done
あるいは、配列に保存することもできます。
shopt -s nullglob
files=(/home/user/file_*)
最初の一致にのみ興味がある場合、または一致が1つしかないことがわかっている場合$files
。には ( から継承された動作 , in (fixed )) の代わりに配列のすべての要素に拡張する一般的に迷惑なbash
動作があるのでファイルを参照できます。しかし、ここでは一度だけ望ましい動作です。$files
${files[0]}
ksh
zsh