gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 05:40:05 25 4
gpt4 key购买 nike

我正在学习 Bash 编程,我找到了这个例子,但我不明白它的意思:

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

特别是在“-e”之后传递给 sed 的参数。

最佳答案

这是一个坏例子;你不应该遵循它。

<小时/>

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

s/pattern/replacement/flagssed 命令,在 man sed 中有详细描述。在本例中,pattern 是一个正则表达式; replacement 是该模式被替换为何时/何处找到的内容;和 flags 描述有关如何完成替换的详细信息。

在这种情况下,s/^\.\///g 分解如下:

  • s 是正在运行的 sed 命令。
  • / 是用于分隔此命令各部分的符号。 (任何字符都可以用作印记,而选择使用 / 来表示此表达的人是出于慈善目的,而不是考虑他们正在努力做什么)。
  • ^\.\/ 是要替换的模式。 ^ 表示仅在开头替换任何内容; \. 仅匹配句点,而 . (这是匹配任何字符的正则表达式);和 \/ 仅匹配 / (与 / 相比,它将继续到此 sed 命令的下一部分,成为所选的印记)。
  • 下一部分是一个空字符串,这就是为什么后面两个符号之间没有内容的原因。
  • flags 部分中的
  • g 表示每行可以发生多次替换。与 ^ 结合使用时,这没有任何意义,因为每一行只能有一个行首;进一步的证据表明编写你的示例的人没有考虑太多。

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

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

  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 内置函数替换 sed:

    # This is much faster than shelling out to any external tool
    filtered_files=${files//.\//}

使用更好的数据结构

而不是运行

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

...如果采用原来的方法就会发生这种情况。

关于linux - 了解 sed 表达式 's/^\.\///g',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30791816/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com