【问题标题】:Space being treated as a delimiter in UNIX array空格在 UNIX 数组中被视为分隔符
【发布时间】:2017-08-09 14:19:06
【问题描述】:

我有一段代码,其中有一个由 / 分隔的字符串。

代码的最后一个元素是一个值“汽车和自行车” 但是代码将空格视为分隔符,我得到了错误的输出。

ARG="s3://this-is-my-bucket/Load/Data/Cars & Bikes"
ARR=(${ARG//// })
S3=${ARR[0]}
AWS=${ARR[1]}
TYPE=${ARR[2]}
FIELD=${ARR[3]}
ITEM=${ARR[4]}
echo $S3
S3:
echo $AWS
this-is-my-bucket
echo $TYPE
Load 
echo $FIELD
Data
echo $ITEM
Cars

我想要的 o/p 是这样的

回显 $ITEM

汽车和自行车

欢迎提出任何建议。

【问题讨论】:

  • 使用代码标记,而不是引用
  • 引用变量以防止分词。
  • 正确答案请参考unix.stackexchange.com/a/92188
  • @Theforgotten- 这不是一个正确的答案。

标签: arrays linux shell unix


【解决方案1】:

设置IFS 将单词分隔符从空格更改为/。当您不想分词时,请将变量放在双引号中。

ARG="s3://this-is-my-bucket/Load/Data/Cars & Bikes"
IFS=/
ARR=($ARG)
S3=${ARR[0]}
AWS=${ARR[2]}
TYPE=${ARR[3]}
FIELD=${ARR[4]}
ITEM=${ARR[5]}
echo "$S3"
echo "$AWS"
echo "$TYPE"
echo "$FIELD"
echo "$ITEM"

注意,由于s3:后面有两个//,所以需要给数组索引加1才能得到以下字段。仅当IFS 包含标准空白字符时,IFS 字符的多个序列才会被视为单个分隔符。

顺便说一句,您应该避免使用大写的变量名。这些是用于环境变量的。

【讨论】:

  • @Barmer - 注意,在 s3: 之后有 2 个 //。所以, IFS=/ 不会解决问题。
  • @ParijatBose 很好,我已经为此调整了索引。
【解决方案2】:

您可以使用read -a/ 作为IFS

s="s3://this-is-my-bucket/Load/Data/Cars & Bikes"
IFS=/ read -ra arr <<< "$s" && declare -p arr

declare -a arr=([0]="s3:" [1]="" [2]="this-is-my-bucket" [3]="Load" [4]="Data" [5]="Cars & Bikes")

否则您可以避免创建数组并直接使用readIFS=/ 中的变量,如下所示:

IFS=/ read -r s3 _ aws type field item <<< "$s" && declare -p s3 aws type field item
declare -- s3="s3:"
declare -- aws="this-is-my-bucket"
declare -- type="Load"
declare -- field="Data"
declare -- item="Cars & Bikes"

【讨论】:

  • 谢谢@anubhava。使用 IFS 会导致回归问题。在我/你提到的代码之后还有更多的代码行。顺便说一句,我们在 unix 路径中有“/”。因此,将 IFS 设置为 / 将 unix 路径也视为分隔符。你能帮我解决如何在使用完成后停止/停用 IFS=/ 吗?
  • IFS=/read 放在同一行中不会设置全局IFS 变量。如果您出于某种原因设置了全局IFS,请使用unset IFS 重置它。
  • 这与shell脚本无关。是 bash,不是 sh。
  • 抱歉不明白
猜你喜欢
  • 1970-01-01
  • 2014-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多