代码之家  ›  专栏  ›  技术社区  ›  Nick Bull

仅在由非转义字符分隔的字符串上迭代

  •  1
  • Nick Bull  · 技术社区  · 8 年前

    假设我有以下字符串:

    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"
    

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

    3 回复  |  直到 8 年前
        1
  •  3
  •   anubhava    8 年前

    您可以使用 gnu grep 在里面 perl 模式:

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

    正则表达式详细信息:

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

    One
    two
    three\ four
    five
    

    这里是 POSIX版本 相同的 grep :

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

    如果要在循环中循环这些字符串:

    while IFS= read -r str; do
       echo "$str"
    done < <(grep -oP '[^\s\\]+(\\.\S+)*' <<< "$var")
    
        2
  •  1
  •   Nick Bull    8 年前

    只是为了扩展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
  •  -1
  •   choroba    8 年前

    使用数组:

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