sed 's/^*//g' 的作用是什么?

sed 's/^*//g' 的作用是什么?

我不明白以下命令在 Unix 中的作用:

sed 's/^*//g'

我尝试在谷歌中搜索它,但没有成功。任何帮助,将不胜感激。

答案1

给定的命令尝试从每行输入的开头sed删除单个字符。*

sed实用程序通常用于对文件或数据流进行逐行文本修改。由于命令行上没有给出文件名操作数,问题中的命令编辑其标准输入流。它将编辑表达式s/^*//g应用于每一行输入,这是一个替换命令,用于删除与正则表达式匹配的任何内容^*(或者更确切地说,它不替换任何内容,这具有相同的效果)。

表达式中的首字母^是一个“锚点”,它强制表达式在行的开头匹配。该*字符在正则表达式中通常是“特殊”的(它允许前一个表达式匹配零次或多次,如ab*,它将匹配a,ababb)。但是,当*是第一个字符时(可能在初始^锚点之后),它匹配文字字符*

这对于 POSIX 来说也是如此基本的正则表达式,这是sed(and grep) 默认使用的。您sed可能还支持 POSIX延长正则表达式,其中*首先(或紧随其后^)是不明确的并且可能会导致错误:

$ sed -E 's/^*//g'
sed: 1: "s/^*//g": RE error: repetition-operator operand invalid

最后g没有任何效果。该标志的意思是“对行上的每个非重叠匹配项重复替换”,但由于表达式通过 锚定到行的开头^,因此至多只有一个这样的匹配项。

例子:

$ printf '%s\n' 'a*a' 'bb*' '***' '*abc'
a*a
bb*
***
*abc

我们的sed表达式预计会*从上面最后两行的开头删除一个单行。

$ printf '%s\n' 'a*a' 'bb*' '***' '*abc' | sed 's/^*//'
a*a
bb*
**
abc

只是表明g在末尾添加没有什么区别:

$ printf '%s\n' 'a*a' 'bb*' '***' '*abc' | sed 's/^*//g'
a*a
bb*
**
abc

直到我们删除锚定后,该g标志才会生效:

$ printf '%s\n' 'a*a' 'bb*' '***' '*abc' | sed 's/*//g'
aa
bb

abc

这种特殊的修改将通过以下方式更有效地执行

tr -d '*'

由于在基本正则表达式中首次出现时*匹配文字字符,因此使用行尾锚点的*表达式将匹配行末尾的单个字符。因此,下面显示了如何删除行尾的字符:*$$**

$ printf '%s\n' 'a*a' 'bb*' '***' '*abc' | sed 's/*$//'
a*a
bb
**
*abc

如您所见,这会影响示例数据的第二行和第三行。

相关内容