これがその仕事をする関数です。巨大な文字列の場合は遅くなる可能性がありますが、任意のコードの実行やパス名の拡張などの警告なしで、問題なく機能します。
#!/bin/bash
parse_quoted_items() {
# Return array is parse_quoted_items_ary
local line=$1
parse_quoted_items_ary=() parse_quoted_items_error=
while [[ $line ]]; do
if [[ $line =~ ^[[:space:]]*\"([^\"]*)\"([[:space:]]+.+|)[[:space:]]*$ ]]; then
parse_quoted_items_ary+=( "${BASH_REMATCH[1]}" )
line=${BASH_REMATCH[2]}
else
parse_quoted_items_error=$line
return 1
fi
done
}
その後、あなたはとして使用することができます
IFS= read -r line < foo.txt
if parse_quoted_items "$line"; do
declare -p parse_quoted_items_ary
else
printf >&2 "There was an error parsing the string at %s\n" "$parse quoted_items_error"
exit 1
fi
これは満足のいく答えではありませんが、文字列を明示的に解析しない(安全な)方法があるとは思えません。