【问题标题】:Iterating over a string separated by unescaped characters only迭代仅由非转义字符分隔的字符串
【发布时间】:2018-11-27 11:30:50
【问题描述】:

假设我有以下字符串:

var="One two three\ four five"

什么命令会有以下代码:

for item in "$(operation on $var)"; do
  echo "$item"
done

并产生以下输出:

One
two
three four
five

或者,我可以在已经用双引号括起来的字符串输入上使用单引号来实现这一点吗?即,我可以拥有字符串

var="One two 'three four' five"

在上述条件下产生相同的输出?

【问题讨论】:

    标签: regex string bash shell


    【解决方案1】:

    您可以在perl 模式下使用gnu grep

    var="One two three\ four five"
    grep -oP '[^\s\\]+(\\.[^\s\\]+)*' <<< "$var"
    

    正则表达式详细信息:

    • [^\s\\]+:匹配任何不是\ 的非空白字符的 1+
    • (: 开始组
      • \\.[^\s\\]+:匹配 \ 后跟任何转义字符,后跟另一个包含 1+ 个非空白和非反斜杠字符的字符串。
    • )*:结束组。匹配该组中的 0 个或多个。

    One
    two
    three\ four
    five
    

    这是相同grepposix版本

    grep -oE '[^\\[:blank:]]+(\\.[^\\[:blank:]]+)*' <<< "$var"
    

    如果你想循环遍历这些字符串:

    while IFS= read -r str; do
       echo "$str"
    done < <(grep -oP '[^\s\\]+(\\.\S+)*' <<< "$var")
    

    【讨论】:

    • 非常好的答案,2 分钟后我可以接受。如果您知道如何使其符合 POSIX 标准...:O 我想我可以让 sed 正确地做一些事情
    • 我也添加了grep的POSIX版本。
    • 你太棒了!谢谢
    • 如果有两个反斜杠或三个反斜杠等,预期的行为是什么?
    【解决方案2】:

    只是为了扩展 anubhava 对第一个案例 ("\ ") 的彻底答案,这里是第二个案例 ("' '") 的答案:

    echo "one two 'three four three and a half' five" | 
      grep -oE "('([^'[:blank:]]+ )+[^'[:blank:]]+'|[^'[:blank:]]+)"
    

    输出:

    one
    two
    'three four three and a half'
    five
    

    【讨论】:

      【解决方案3】:

      使用数组:

      arr=(one two 'three four' five)
      for item in "${arr[@]}" ; do
          echo "$item"
      done
      

      【讨论】:

      • 整个字符串都在双引号内,所以我不相信这会起作用。
      • @NickBull:字符串来自哪里?
      • 函数参数,必须引用以不干扰尾随参数
      • @NickBull:所以修复它,使用带有特殊参数的单独参数,意思是“这是最后一个”。
      • 如果是那么简单的 choroba ;) 不幸的是,这是输入源的格式。该函数用于来自已经存在的应用程序的单个字符串的输入,我无法控制输出的格式。将其放在末尾或开头对此没有影响。因此,虽然我同意如果我可以控制输入,那是个好主意,但事实并非如此。即使我把它写成一个函数,参数按照你的建议格式化,我仍然需要在调用函数之前以这种方式格式化字符串。
      猜你喜欢
      • 2010-10-19
      • 1970-01-01
      • 2023-03-07
      • 2020-09-19
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多