globパターンで定義された変数を使用したBashの置換

globパターンで定義された変数を使用したBashの置換

次の例では、この問題について説明します。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]}kshzsh

おすすめ記事