String 在“上拆分字符串”;创建一个空字符串

String 在“上拆分字符串”;创建一个空字符串,string,bash,shell,ksh,String,Bash,Shell,Ksh,我在shell脚本中使用了一个命令,该命令返回多个字符串,每个字符串都包含在“中。由于我需要将这些字符串中的每一个作为数组的单独元素,因此我使用“作为分隔符来拆分这些字符串集合,如下所示: IFS='"' arr=($(command that returns multiple strings enclosed in "")) 现在,由于每个字符串的开头都有一个“字符,因此我的脚本将每个字符串拆分为一个空白字符串和字符串本身。例如,字符串“foo”“bar”将分为(空字符串)、foo、(再次为

我在shell脚本中使用了一个命令,该命令返回多个字符串,每个字符串都包含在
中。由于我需要将这些字符串中的每一个作为数组的单独元素,因此我使用
作为分隔符来拆分这些字符串集合,如下所示:

IFS='"'
arr=($(command that returns multiple strings enclosed in ""))
现在,由于每个字符串的开头都有一个
字符,因此我的脚本将每个字符串拆分为一个空白字符串和字符串本身。例如,字符串
“foo”“bar”
将分为
(空字符串)、
foo
(再次为空字符串)和
bar
。所以我的数组最终有4个元素,而不是2个

有两种方法可以克服这一问题,任何帮助实施这两种方法都会有帮助:

  • 在拆分时以某种方式去除空白
  • 使用空格创建数组,然后创建另一个数组,并仅将第一个数组中的非空格元素插入第二个数组

  • 我将答案标记为bash和ksh,因为解决方案是bash也可以接受。谢谢

    除非带引号的字符串包含换行符,否则可以使用
    xargs
    将带引号的字符串处理为NUL分隔的单词列表:

    array=( )
    while IFS= read -r -d '' piece; do
      array+=( "$piece" )
    done < <(command-that-returns-multiple-quoted-strings | xargs printf '%s\0')
    

    如果您想将字符串存储在双引号中,而忽略其余字符串,下面是一个正确处理
    awk
    解决方案:

    arr=(); 
    while IFS= read -r -d '' item; do 
       arr+=("$item"); 
    done < <(cmd | gawk -v RS='"[^"]*"' 'RT { gsub("\"", "", RT); printf RT"\0"}');
    

    arr=($(…)
    从一开始就是不好的做法。事实上,没有一个地方是人们应该去做的。如果你能控制输出,你可以使用
    eval arr=($(echo'foo'bar'))
    。这可能有潜在的危险,例如
    eval arr=($(echo'foo”“$(echo-hazardous)”)
    `(如果您想在定界符上拆分单词,请考虑<代码> IFS=' 'Read -R-A ARR,它将替换当前目录中的文件名列表,以代替<代码>”/“代码>,除非在扩展之前关闭GOBBIN。”“总的来说,这只是一个仓促的尝试,它不能正常工作……我试图想出一个同样可以接受
    的解决方案,并且我已经更新了我的答案。如果将awk方法用于通用用例,我仍然认为它相对脆弱。如果我用
    测试它,“foo bar”“baz qux”one\two-three”四个
    ,一个,
    两个
    三个
    四个
    都没有出现在输出中,而
    xargs
    得到了很好的结果。@CharlesDuffy-hm,它对我来说适用于
    awk
    declare-a arr='([0]=“foo-bar”[1]=“baz-qux”[2]=)“
    。这正是我想象中OP想要的。它忽略了不在引号中的字符串。啊——这不是我期望OP在这些情况下想要的(标记为的问题是显式要求解析相当于shell的行为,这是一个相当常见的请求),但我想这是一个需要他们回答的问题。(当我读这个问题时,他们不希望引号外除了空格之外还有其他内容,但希望保留字符串拆分后除空格以外的所有内容)。
    arr=(); 
    while IFS= read -r -d '' item; do 
       arr+=("$item"); 
    done < <(cmd | gawk -v RS='"[^"]*"' 'RT { gsub("\"", "", RT); printf RT"\0"}');
    
    readarray -d '' arr < <(cmd | gawk -v RS='"[^"]*"' 'RT { gsub("\"", "", RT); printf RT"\0"}')