上猛砸符串分割,分配段阵列 [英] Bash split string on delimiter, assign segments to array

查看:198
本文介绍了上猛砸符串分割,分配段阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

庆典,我想改变一个路径般的环境变量的可能的包含空格隔开的元素到阵列,使的​​确定的元素承载空间做不会导致字分裂,表现为多元素。


PATH_VARIABLE 是有问题的变量。

取消:dodecaedro:每:tirare:每:我丹妮是变量的内容

所需阵列 _to有无 6 元素,不是 7

  0)UN
1)dodecaedro
2)每
3)tirare
4)每
5)我丹妮

在刁钻条目可能是空间分隔值:我丹妮

我要寻找绝对的最优雅正确的方式来实现这一目标。

局限性:它必须与我的庆典版本: v3.2.48(1)-release


蟒蛇这样做只是美丽的像这样:

 >>> V ='联合国:dodecaedro:每:tirare:每:我丹妮
>>> LEN(v.split(':'))
6

作品。显示了我所期待的。


什么是做在我们敬爱的庆典的最佳方式

你能明确我尝试改善 4

在这里,我尝试


 #!/斌/庆典PATH_VARIABLE ='UN:dodecaedro:每:tirare:每:我丹妮#错误
A1 =($(回声$ PATH_VARIABLE | TR':'的'\\ n'))#错误
A2 =($(
  而读path_component;做
  回声$ path_component
  完成< ≤(回声$ PATH_VARIABLE| TR':'的'\\ n')
))#工程,它是优雅..但我没有庆典4!
#readarray -t A3< ≤(回声$ PATH_VARIABLE| TR':'的'\\ n')#作品,但它看起来笨重给我:(
I = 0
而读线;做
  A4 [我++] = $行
完成< ≤(回声$ PATH_VARIABLE| TR':'的'\\ n')N = $ {#A4 [@]}
为((i = 0; I< N;我++));做
  printf的'%2D)%S \\ n'$ I$ {A4 [I]}
DONE


我的环境

庆典 v3.2.48(1) - 发布

OSX OS X v10.8.3(建12D78)



解决方案

  F(){
  当地IFS =:
  当地富
  设置-f#禁止水珠扩张
  富=($ @)#故意不带引号
  集+ F
  printf的%d个\\ N'$ {#foo的[@]}
  printf的'%s的\\ n'$ {foo的[@]}
}F'UN:dodecaedro:每:tirare:每:我丹妮
6
联合国
dodecaedro

tirare

我丹妮

修改吉姆·麦克纳马拉的答案,你可以只重置IFS:

  oIFS =$ IFS
富='联合国:dodecaedro:每:tirare:每:我丹妮
IFS =:ARR =($富)
IFS =$ oIFS

我preFER功能范围,因为它保护IFS变化从出血到全球范围,而不需要特殊照顾重置。

编辑和解释:

作为澄清的问题:在第二个例子中,IFS设置的确实的改变全局变量。这之间的差异显着:

  IFS =:ARR =($富)

和这样的:

  IFS =:读-a ARR<<< $富

是,前者是两个可变分配,没有命令,而后者的一个简单的命令的(见的简单的命令的在男人(1 )庆典

演示:

  $回声$ BASH_VERSION
3.2.48(1)-release
$回声$ IFS
$ foo的='UN:dodecaedro:每:tirare:每:我丹妮
$ IFS =:读-a ARR<<< $富
$回声$ {#ARR [@]}
6
$回声$ IFS
$ IFS =:ARR1 =($富)
$回声$ {#ARR1 [@]}
6
$回声$ IFS

In , I would like to transform a PATH-like environment variable that may contain space-separated elements into an array, making sure elements bearing spaces do not cause word-splitting, appearing as "multiple elements".


Let PATH_VARIABLE be the variable in question.

Let un:dodecaedro:per:tirare:per:i danni be the content of the variable.

It is intended for the desired array _to have 6 elements, not 7.

0) un
1) dodecaedro
2) per
3) tirare
4) per
5) i danni

The "tricky" entry may be the space-separated value: i danni.

I am looking for the absolute most elegant and correct way to achieve this.

Limitation: it must work with my version: v3.2.48(1)-release


In this is done just beautifully as so:

>>> v='un:dodecaedro:per:tirare:per:i danni'
>>> len(v.split(':'))
6

Works. Shows what I am looking for.


What's the best way to do this in our beloved ?

Can you specifically improve on my attempt 4?

Here my attempts


#!/bin/bash

PATH_VARIABLE='un:dodecaedro:per:tirare:per:i danni'

# WRONG
a1=($(echo $PATH_VARIABLE | tr ':' '\n'))

# WRONG
a2=($(
  while read path_component; do
  echo "$path_component"
  done < <(echo "$PATH_VARIABLE" | tr ':' '\n')
))

# WORKS, it is elegant.. but I have no bash 4!
# readarray -t a3 < <(echo "$PATH_VARIABLE" | tr ':' '\n')

# WORKS, but it looks "clunky" to me :(
i=0
while read line; do
  a4[i++]=$line
done < <(echo "$PATH_VARIABLE" | tr ':' '\n')

n=${#a4[@]}
for ((i=0; i < n; i++)); do
  printf '%2d) %s\n' "$i" "${a4[i]}"
done


My environment

v3.2.48(1)-release

OS X v10.8.3 (build 12D78)


解决方案

f() {
  local IFS=:
  local foo
  set -f # Disable glob expansion
  foo=( $@ ) # Deliberately unquoted 
  set +f
  printf '%d\n' "${#foo[@]}"
  printf '%s\n' "${foo[@]}"
}

f 'un:dodecaedro:per:tirare:per:i danni'
6
un
dodecaedro
per
tirare
per
i danni

Modifying Jim McNamara's answer, you could just reset IFS:

oIFS="$IFS"
foo='un:dodecaedro:per:tirare:per:i danni'
IFS=: arr=( $foo )
IFS="$oIFS"

I prefer the function scope because it protects IFS changes from bleeding into the global scope without requiring special care to reset it.

Edits and explanations:

As a matter of clarification: In the second example, the IFS setting does change the global variable. The salient difference between this:

IFS=: arr=( $foo )

and this:

IFS=: read -a arr <<< "$foo"

is that the former is two variable assignments and no commands, and the latter is a simple command (see simple command in man (1) bash.)

Demonstration:

$ echo "$BASH_VERSION"
3.2.48(1)-release
$ echo "$IFS"


$ foo='un:dodecaedro:per:tirare:per:i danni'
$ IFS=: read -a arr <<< "$foo"
$ echo "${#arr[@]}"
6
$ echo "$IFS"


$ IFS=: arr1=( $foo )
$ echo "${#arr1[@]}"
6
$ echo "$IFS"
:

这篇关于上猛砸符串分割,分配段阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆