了解sed表达式' s /^\.\/// g'

时间:2015-06-11 21:30:48

标签: linux sed

我正在学习Bash编程,我找到了这个例子,但我不明白这意味着什么:

filtered_files=`echo "$files" | sed -e 's/^\.\///g'`

特别是在' -e'之后传递给sed的论点。

2 个答案:

答案 0 :(得分:2)

这是一个坏榜样;你不应该遵循它。

首先,了解手边的sed表达式。

s/pattern/replacement/flagssed命令,在man sed中详细介绍。在这种情况下,pattern是正则表达式; replacement是什么样的模式被替换为何时/何时找到; flags描述了如何进行替换的详细信息。

在这种情况下,s/^\.\///g按如下方式细分:

  • s是正在运行的sed命令。
  • /是用于分隔此命令各部分的印记。 (任何角色都可以用作一个印记,选择使用/作为这个表达的人是慈善的,不会考虑他们在做什么很辛苦)。
  • ^\.\/是要替换的模式。 ^意味着这只会在开头时替换任何内容; \.只匹配一个句点,与.匹配(这是匹配任何字符的正则表达式);并且\/仅匹配/(vs /,这将继续执行此sed命令的下一部分,即选定的sigil。
  • 下一部分是一个空字符串,这就是为什么以下两个符号之间没有内容。
  • g部分中的
  • flags表示每行可以发生多次替换。与^一起,这没有任何意义,因为每行只能有一个行首;进一步的证据表明,写你的例子的人并没有多想。

使用相同的数据结构,做得更好:

以下所有内容在处理任意文件名时都有错误,因为在标量变量中存储任意文件名通常都是错误的。

  1. 仍在使用sed

    # Use printf instead of echo to avoid bugginess if your "files" string is "-n" or "-e"
    # Use "@" as your sigil to avoid needing to backslash-escape all the "\"s
    filtered_files=$(printf '%s\n' "$files" | sed -e 's@^[.]/@@g'`)
    
  2. 用bash builtin替换sed

    # This is much faster than shelling out to any external tool
    filtered_files=${files//.\//}
    
  3. 使用更好的数据结构

    而不是运行

    files=$(find .)
    

    ...代替:

    files=( )
    while IFS= read -r -d '' filename; do
      files+=( "$filename" )
    done < <(find . -print0)
    

    将文件存储在数组中;它看起来很复杂,但它更安全 - 即使文件名包含空格,引号字符,换行文字等也能正常工作。

    此外,这意味着您可以执行以下操作:

    # Remove the leading ./ from each name; don't remove ./ at any other position in a name
    filtered_files=( "${files[@]#./}" )
    

    这意味着名为

    的文件
    ./foo/this directory name (which has spaces) ends with a period./bar
    

    将正确转换为

    foo/this directory name (which has spaces) ends with a period./bar
    

    而不是

    foo/this directory name (which has spaces) ends with a periodbar
    

    ......原始方法会发生这种情况。

答案 1 :(得分:0)

man sed。特别是:

-e script, --expression=script
    add the script to the commands to be executed

   s/regexp/replacement/
          Attempt  to match regexp against the pattern space.  If success-
          ful,  replace  that  portion  matched  with  replacement.    The
          replacement may contain the special character & to refer to that
          portion of the pattern space  which  matched,  and  the  special
          escapes  \1  through  \9  to refer to the corresponding matching
          sub-expressions in the regexp.

在这种情况下,它会用空字符串替换行开头./的任何出现,换句话说,将其删除。