linux 理解sed表达式的/^\.\/g'

vs91vp4v  于 2023-11-17  发布在  Linux
关注(0)|答案(2)|浏览(232)

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

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

字符串
特别是在'-e'之后传递给sed的参数。

wqnecbli

wqnecbli1#

这是个坏榜样,你不应该学它.

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

s/pattern/replacement/flags是一个sed命令,在man sed中有详细描述。在本例中,pattern是一个正则表达式; replacement是该模式在何时/何地被替换的内容; flags描述了如何进行替换的细节。
在这种情况下,s/^\.\///g分解如下:

  • s是正在运行的sed命令。
  • /是用来分隔这个命令的各个部分的符号(任何字符都可以用作符号,选择使用/来表示这个表达式的人是仁慈的,没有考虑他们在做什么)。
  • ^\.\/是要替换的模式。^意味着它只在开始时替换任何内容; \.只匹配一个句点,而.(它是正则表达式,用于匹配任何字符);而\/只匹配/(与/相比,/将继续到这个sed命令的下一部分,即所选的sigil)。
  • 下一个部分是一个空字符串,这就是为什么后面两个符号之间没有内容。
  • 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'`)

字符串
1.使用bash内置函数替换sed

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

使用更好的数据结构

而不是运行

files=$(find .)


. instead:

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


......这在最初的方法中会发生。

e4yzc0pl

e4yzc0pl2#

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.


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

相关问题