bourne shell会出现意想不到的断字

时间:2017-01-05 20:20:44

标签: macos shell osx-yosemite

使用MAC OS X和bourne shell:

我喜欢遍历一个项目列表,其中一些项目包括空白。 每个项目应作为一个整体对待,但它们将按如下所示进行拆分。 如果我"硬编码"就像这样,没关系:

echo "hard coded :\n"
for i in 'a a a' 'bcd' 'e e'
do
 echo "$i"
done

但是将相同的字符串放入变量中是错误的:

echo "\nsecond loop:\n"
#
# str is normally coming from a comma substitution
str="'a a a' 'bcd' 'e e'"
echo $str
for i in  ${str}
do
 echo "$i"
done

结果是:

hard coded :
a a a
bcd
e e

第二个循环:

'a a a' 'bcd' 'e e'
'a
a
a'
'bcd'
'e
e'

3 个答案:

答案 0 :(得分:1)

以下是一些定义CSV的代码,然后在不需要xargs或其他外部程序的情况下对其进行迭代。这是完全可移植的POSIX,可以在bash或任何/bin/sh中使用。

#!/bin/sh
str="a a a,*,e e"
echo $str
while [ "$str" != "${str#*,}" ]; do
  echo "${str%%,*}" # just the first CSV item
  str="${str#*,}"   # remove the first CSV item
done
echo "$str"         # the final (or only) CSV item

这使用shell变量parameter expansion

原始答案

你可以使用不同的分隔符并设置$IFS i 输入 f ield s eparator)来键入它。我在这里使用逗号,因为您暗示原始输入使用逗号分隔值:

#!/bin/sh -f

str="a a a,bcd,e e"
echo $str
OLDIFS="$IFS"
IFS=","
for i in  ${str}
do
 echo "$i"
done
IFS="$OLDIFS"

这会产生:

a a a,bcd,e e
a a a
bcd
e e

如果输入中存在星号或类似字符,shell的-f标志对于抑制通配符扩展(“globbing”)非常重要。

这适用于POSIXBournebashkorn以及该家庭中的大多数其他人。

答案 1 :(得分:0)

使用数组:

strings=('a a a' 'bcd' 'e e')
for i in "${strings[@]}"
do
 echo "$i"
done

答案 2 :(得分:0)

如果你想要引用类似shell的字符串拆分,请使用xargs

str="'a a a' 'bcd' 'e e'"
echo "$str" | xargs printf '%s\n'

...将发出:

a a a
bcd
e e

但是,一般来说,正确的事情是避免程序设计需要这种行为。