【问题标题】:How can I use a Bash array as input to a command?如何使用 Bash 数组作为命令的输入?
【发布时间】:2011-07-27 03:22:04
【问题描述】:

比如说,我有以下数组:

files=( "foo" "bar" "baz fizzle" )

我想通过一个命令来传递这个数组的内容,比如sort,就像每个元素在文件中的一行一样。当然,我可以将数组写入临时文件,然后将临时文件用作sort 的输入,但如果可能的话,我想避免使用临时文件。

如果"bar fizzle" 没有那个空格字符,我可以这样做:

echo ${files[@]} | tr ' ' '\012' | sort

有什么想法吗?谢谢!

【问题讨论】:

    标签: arrays bash newline pipe


    【解决方案1】:
    sort <(for f in "${files[@]}" ; do echo "$f" ; done)
    

    【讨论】:

    • 完美!我不知道&lt;() 语法。谢谢伊格纳西奥!
    • 我也不知道(直到现在)"${files[@]}" 扩展为 "foo" "bar" "baz fizzle" 而不是 "foo bar baz fizzle"
    • 这个特定的方法叫什么?
    【解决方案2】:

    另一种解决方案:

    printf "%s\n" "${files[@]}" | sort
    

    【讨论】:

    • 虽然这可行,但它似乎依赖于 printf 记录不充分的行为:事实上,与 C 版本的 printf 不同,printf 命令行实用程序循环遍历格式字符串,直到没有更多论据。如果您查看 the man page for printf(1) under Mac OS X,它会在 BUGS 部分讨论这个问题。不过,我仍然会给你投票;)
    • @splicer:我认为BUGS部分的注释是在谈论别的东西;主要的说明部分说“格式字符串会根据需要重复使用以满足参数。” bash(1) man page 在其 printf 内置函数中有类似的注释。
    【解决方案3】:
    SAVE_IFS=$IFS
    IFS=$'\n'
    echo "${files[*]}" | sort
    IFS=$SAVE_IFS
    

    当然,如果数组值中有换行符,它将无法正常工作。

    【讨论】:

      【解决方案4】:

      对于文件排序,我建议以零终止模式排序(以避免在文件名或路径中嵌入换行符时出错):

      files=(
      $'fileNameWithEmbeddedNewline\n.txt'
      $'saneFileName.txt'
      )
      
      echo ${#files[@]}
      
      sort <(for f in "${files[@]}" ; do printf '%s\n' "$((i+=1)): $f" ; done)
      sort -z <(for f in "${files[@]}" ; do printf '%s\000' "$((i+=1)): $f" ; done) | tr '\0' '\n'
      
      printf "%s\000" "${files[@]}" | sort -z | tr '\0' '\n'
      find . -type f -print0 | sort -z | tr '\0' '\n'
      

      sort -z 读取和写入零终止行!

      【讨论】:

      • @splicer NUL-terminated 对于数据列表仍然是最安全的,许多程序都能够使用和生成它们。
      猜你喜欢
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-07
      • 2017-01-13
      • 2012-07-10
      相关资源
      最近更新 更多