使用空格将字符串(存储在变量中)拆分为多个单词,而不是双引号内的空格

时间:2013-06-27 08:59:13

标签: bash sed awk

我正在尝试为我编写一个复杂的脚本,我的目标是执行以下操作。我有一个字符串,看起来像这样:

2012 2013 "multiple words"

我的目标是将每个这些放入按空格分割的数组中,但仅限于单个字匹配,而不是用双引号括起来的那些。那些应该被认为是一个词。所以我的想法是分两步完成。首先匹配那些是倍数的单词,从字符串中删除那些,然后在由空格分割的另一个迭代中 很遗憾,我无法找到有关如何echo匹配的帮助。到目前为止,我有这个:

array=$(echo $tags | sed -nE 's/"(.+)"/\1/p')

但这会导致(在OS X上):

2012 2013 multiple words

预期结果:

array[1]="2012"
array[2]="2013"
array[3]="multiple words"

我怎么会遇到这类问题?

感谢。

5 个答案:

答案 0 :(得分:20)

eval是邪恶的,但这可能是方便的一种情况之一

str='2012 2013 "multiple words"'
eval x=($str)
echo ${x[2]}
multiple words

或者使用更新版本的bash(在4.3上测试)

s='2012 2013 "multiple words"'
declare -a 'a=('"$s"')'
printf "%s\n" "${a[@]}"
2012
2013
multiple words

答案 1 :(得分:4)

$ grep -Eo '"[^"]*"|[^" ]*' <<< '2012 2013 "multiple words"'
2012
2013
"multiple words"

也就是说,打印匹配

的字符串
  1. 引用后跟任何数字(甚至为零)的非引号,后跟引号或
  2. 一系列不包含引号或空格的字符。
  3. 当然,这不会处理复杂的情况,例如跨越多行或转义引号的引号(使用像SQL这样的双引号或像shell这样的反斜杠)。

答案 2 :(得分:2)

你可以直接做:

arr=(2012 2013 "multiple words")

echo ${#arr[@]} # gives 3
echo ${arr[2]} # gives "multiple words"

编辑:不确定它是否对OP有帮助,但以下也会有效

str='2012 2013 "multiple\ words"'
read -a arr <<< $str
echo ${#arr[@]} # gives 3
echo ${arr[2]} # gives "multiple words"

答案 3 :(得分:1)

以下内容将产生您想要的结果:

tags='2012 2013 "multiple words"'
IFS=$'\n'; array=($(echo $tags | egrep -o '"[^"]*"|\S+'))

结果是ZSH:

echo ${array[1]} # 2012
echo ${array[2]} # 2013
echo ${array[3]} # "multiple words"

结果是BASH:

echo ${array[0]} # 2012
echo ${array[1]} # 2013
echo ${array[2]} # "multiple words"

适用于OSX。

答案 4 :(得分:0)

这是一个小的Python脚本,用于解析空格分隔的csv,同时尊重引用的字段:

$ python -c '
import csv, fileinput
for line in csv.reader(fileinput.input(), delimiter=" "):
   for word in line:
      print word
' test.csv
2012
2013
multiple words

因为它使用fileinput模块,所以也在管道(或变量中的字符串)中工作:

$ str='2012 2013 "multiple words"'
$ echo $str | python -c '
import csv, fileinput
for line in csv.reader(fileinput.input(), delimiter=" "):
   for word in line:
      print word
' 
2012
2013
multiple words