我正在尝试为我编写一个复杂的脚本,我的目标是执行以下操作。我有一个字符串,看起来像这样:
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"
我怎么会遇到这类问题?
感谢。
答案 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"
也就是说,打印只匹配
的字符串当然,这不会不处理复杂的情况,例如跨越多行或转义引号的引号(使用像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