我想知道它对与 sed 命令一起使用的以下脚本的真正作用。
sed -e 's:<F0_M>:<o,f0,male>:' \
-e 's:<F0_F>:<o,f0,female>:' \
-e 's:([0-9])::g' \
-e 's:<sil>::g' \
-e 's:([^ ]*)$::' | \
第一个和第二个脚本看起来我们正在将文本类型转换<F0_F>
为<o,f0,female>
.但最后三个涉及'::','g' and '$'
符号的情况又如何呢?在大多数文档中,他们在大多数脚本中使用了“\”和“/”。但在这里他们使用了':'
斜线而不是斜线。有人可以解释一下以上三个脚本吗?
答案1
标准分隔符sed
在命令中使用的是/
,如在这样的命令中:
sed -e s/foo/bar/g < input > output
但是,如果该s
命令后面跟着不同的字符,那成为该特定表达式的分隔符。
/
当分隔符本身需要出现在命令中时,使用非分隔符很常见,因此需要仔细注意逃跑。例如,/
在处理 Unix 路径的脚本中处理分隔符很烦人。
这里的情况似乎并非如此,所以我假设该命令的作者只是更喜欢:
作为命令中的分隔符sed
。
您的命令有五个表达式:
s:<F0_M>:<o,f0,male>:
<F0_M>
这会将输入每行上的第一个实例替换为<o,f0,male>
输出中的。如果该行的输入中有多个匹配项,则后续匹配项将被保留。
单引号只是阻止 shell 解释表达式中的任何字符。它们都按字面意思传递给sed
命令。
s:<F0_F>:<o,f0,female>:
与上述情况类似,只是明显针对异性。
s:([0-9])::g
从输入行中删除括号中的所有单个数字。
与前两个表达式不同,此表达式会影响每行上的所有实例,因为尾随g
表示“全局”。
请注意,它仅适用于个位数。(42)
例如,它不会对 做任何事情。
s:<sil>::g
<sil>
写入输出时,从输入的每一行中删除所有实例。
s:([^ ]*)$::
如果行尾不包含空格,则删除该行末尾带括号的字符。还删除行尾的一对空括号。
有关于这些主题sed
和正则表达式的整本书。单一答案确实不适合学习整个主题。
上面的表达式在这方面实际上有点棘手:$
将正则表达式(或简称 regex)固定到行尾和^
行首,但^
该表达式中的含义有所不同。
我建议你阅读掌握正则表达式作者:杰弗里·弗里德尔。