用 sed 或任何其他工具替换部分匹配的正则表达式

用 sed 或任何其他工具替换部分匹配的正则表达式

我需要替换与某个正则表达式匹配的文件部分上的字符。准确地说,我需要删除格式-不正确的降价链接中的空格,例如:

[This is my link](actual bad link.md)

应该变成:

[This is my link](actual-bad-link.md)

(我可以在 sed 中匹配以正则表达式开头和结尾的内容.md),但我不知道如何告诉 sed 仅替换匹配表达式中的空格。有没有办法做到这一点(也可能使用另一个命令行工具,例如 awk)?

谢谢。

(编辑:为了最小化,我会对任何用 替换和.md)之间的所有空格的命令感到满意-

答案1

对于每行一个实例,并且没有嵌套括号,您可以使用matchand执行类似的操作substr

$ echo '[This is my link](actual bad link.md) other stuff' | awk '
    match($0,/\([^)]*\.md\)/){
      s = substr($0,RSTART,RLENGTH); gsub(/ /,"-", s); 
      print substr($0,1,RSTART-1) s substr($0,RSTART+RLENGTH)}
  '
[This is my link](actual-bad-link.md) other stuff

GNU awk 有一个非标准扩展来将匹配组捕获到数组中,但在我看来,它在这里并没有给你带来太多好处。

虽然您可以循环来match实现全局替换,但 Perl 可能是更好的选择。

$ echo '[This is my link](actual bad link.md) other stuff' | perl -pe '
    s{(\(.*?\.md\))}{$1 =~ s/ /-/gr}ge
  '
[This is my link](actual-bad-link.md) other stuff

答案2

您可以使用带有标志的tr命令,该命令需要两个参数,第一个参数是要替换的字符,第二个参数是要替换的字符。tr-t

cat data | tr -t " " "-" 

这将替换所有空格,-但拉出链接的后半部分应该很简单。EDIT: Here is agrep command to pull out whats between the( )`

grep -Po '(?<=\().*(?=\))'

编辑:这是一个如何使用核心实用程序来完成此操作的示例。该脚本也可以缩短,我使用变量来尝试使其更易于阅读。grepsedawk任何这些命令都可用于产生相同的输出。

data="[This is my link](actual bad link.md)"
r=$(echo $data | grep -Po '(?<=\().*(?=\))')
n=$(echo $data | grep -Po '(?<=\().*(?=\))' | tr -s ' ' '-')
t=$(echo $data | sed "s|${r}|${n}|")

echo $t

相关内容