申し訳ありません。私はシェルスクリプトに初めて触れました。コマンドに関連するオプションを含む変数がありますfind
。
TYPE=("-type f")
NAME=("-name \"*log*\"")
オプションを含む変数を関連コードに入れてみました。
- これは働きます:
次のように生成します(サンプル出力)。LST_FILE=$(find ${2} ${TYPE} -mmin +${HOUR_TO_MIN})
viv/clean/prototype/asdadsadsa.log viv/clean/prototype/logo viv/clean/prototype/sadsadasdas.log.gz viv/clean/prototype/prototype/log viv/clean/prototype/prototype/fewfasfs viv/clean/prototype/prototype/og
- しかし、追加しようとすると、
${NAME}
目的のファイルを検索するためのキーワード名をキャプチャできず、結果はありません。
(結果0個生成)LST_FILE=$(find ${2} ${TYPE} ${NAME} -mmin +${HOUR_TO_MIN})
問題は、ワイルドカード、特殊文字、または同様のものに関連しているようです。関連事例のご提案に心から感謝します。
ベストアンサー1
これには2つの問題があります。最初の問題は、2つの変数を1つの要素しか持たない配列として定義し、コマンドfind
で単純なスカラー変数として使用することです。これにより、bashは各配列の最初の要素を丁寧に返します。
第二に、C.Aknesilが指摘したように、bashは変数の拡張後に二重引用符を削除しません。実際、それは実際には問題ではありません。問題は、あなたがそれを知らないのか、bashがなぜこのように動作するのかということです。
この試み:
TYPE=(-type f)
NAME=(-name '*log*')
'*log*'
bash が glob を拡張せずに現在のディレクトリに一致するすべてのファイルを配列に追加するには、ここに引用符が必要です。
次に、次のように使用する必要がありますfind
。
find "$2" "${TYPE[@]}" -mmin "+$HOUR_TO_MIN"
または
find "$2" "${TYPE[@]}" "${NAME[@]}" -mmin "+$HOUR_TO_MIN"
ちなみに、ここで$2
、とはすべて$HOUR_TO_MIN
二重引用符で囲む必要がありますが、{}
周囲の文字と区別する必要はないので、中括弧は必要ありません。たとえば$2
必須ではありませんが、{}
次${2}3
のように解釈されるので必須です$23
。いいえたとえば、「$2の後に3が続きます」)は、それらなしでシェルによって実行されます。
$HOUR_TO_MIN
引用しなくても大丈夫でしょう(おそらくスクリプトで定義されていて、空白などの問題文字がないでしょう)。しかし、引用しても何の害もありません。知るあなたがこのようなことをしたくないことを確信してください。なぜ)」は開発する価値がある良い習慣です。
$2
ただし、これはユーザーがスクリプトの引数として提供し、その中に何でも含めることができ、常に引用する必要があります。
注:ファイル名には、スペース、タブ、改行などのスペースから、およびなどのシェルメタ文字まで、あらゆるLST_FILES=$(find ...)
種類の迷惑な文字を含めることができるため、これは良い考えではありません。唯一の役割は;
&
>
|
できないファイル名のNUL。これは、NULが信頼できる唯一のファイル名区切り文字であることを意味します。どのファイル名。
代わりに、変数から find の出力が必要な場合は配列を使用し、たとえばfind
NUL を出力として使用するように指示します-print0
。
mapfile -d '' LST_FILES < <(find "$2" "${TYPE[@]}" "${NAME[@]}" -mmin "+$HOUR_TO_MIN" -print0)
このmapfile
コマンド(とも呼ばれるreadarray
)はstdinから読み込み、それを使用して配列を埋めます。この例では、NULを区切り文字として使用することを示します-d ''
。
次のことを試して、それがどのように機能するかを直接確認してください。
$ mkdir junk
$ cd junk
$ touch foo bar baz 'file with spaces' $'file\nwith\nLFs'
$ ls
bar baz file?with?LFs file with spaces foo
$ mapfile -d '' LST_FILES < <(find . -type f -print0)
$ declare -p LST_FILES
declare -a LST_FILES=([0]="./foo" [1]=$'./file\nwith\nLFs' [2]="./baz"
[3]="./file with spaces" [4]="./bar")
$ echo "${#LST_FILES[@]}" # use ${#...} to count elements in an array
5
$ for f in "${LST_FILES[@]}"; do echo "$f" ; done
./foo
./file
with
LFs
./baz
./file with spaces
./bar