如何在冒号之前替换正则表达式?

how to regex replace before colon?

这是我的原始字符串:

NetworkManager/system connections/Wired 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1

我只想在“:”

之前的所有 space 中添加反斜杠

所以,这就是我最终想要的:

NetworkManager/system\ connections/Wired\ 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1

我需要在 bash 中执行此操作,因此,sed、awk、grep 对我来说都可以。

我试过使用 sed,但 none 成功了

echo NetworkManager/system connections/Wired 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1 | sed 's/ .*\(:.*$\)/\ .*/g'
echo NetworkManager/system connections/Wired 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1 | sed 's/\( \).*\(:.*$\)/\ .*/g'
echo NetworkManager/system connections/Wired 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1 | sed 's/ .*\(:.*$\)/\ /g'
echo NetworkManager/system connections/Wired 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1 | sed 's/\( \).*\(:.*$\)/\ /g'

感谢您回答我的问题。 我还是Whosebug的新手,我不知道如何控制评论的格式。 所以,我只是编辑我原来的问题

我的真实故事是:

当我执行 grep 或使用 cscope 搜索关键字时,例如 /etc 文件夹下的“address1”。 结果会是这样的:

./NetworkManager/system connections/Wired 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1

如果我使用 vim 打开光标下的文件,假设我的 vim 光标现在位于单词“NetworkManager”, 那么vim就会理解为

"./NetworkManager/system"

这就是为什么我想在space之前添加“\”,这样搜索结果会更加vim友好:)

我确实尝试过更改cscope的源代码,但很难完全实现。所以必须做一个 post 替换:(

这可以在 awk 程序中简单地完成,使用您显示的示例,请尝试执行以下操作。

awk 'BEGIN{FS=OFS=":"} {gsub(/ /,"\\&",)} 1' Input_file

解释: 简单的解释就是,将本程序的字段分隔符和输出字段分隔符设置为:。然后在主程序中使用awkgsub(全局替换)函数。仅在第一个字段中用 \ 替换 space(根据 OP 的说明,它应该在 : 之前完成)然后打印行。

如果您只想在字符串中存在 : 时进行替换,您可以检查是否至少有 2 列,将(输出)字段分隔符设置为冒号。

数据:

cat file                                                                                                                                       michaelvandam@Michaels-MacBook-Pro
NetworkManager/system connections/Wired 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1
NetworkManager/system connections/Wired 1.nmconnection 14 address1=10.1.10.71/24,10.1.10.1%

awk中的示例:

awk 'BEGIN {FS=OFS=":"}{if(NF>1)gsub(" ","\ ",)}1' file

输出

NetworkManager/system\ connections/Wired\ 1.nmconnection:14 address1=10.1.10.71/24,10.1.10.1
NetworkManager/system connections/Wired 1.nmconnection 14 address1=10.1.10.71/24,10.1.10.1

我的回答很丑陋,我认为 是唯一的,但我已经花时间写了我的并且它有效(它是一步一步写的,但它是一个单行命令):

我受到启发 HatLess answer:

首先用 cut 获取 : 之前的文本(我将字符串放在文件中以便于阅读,但这适用于 echo):

cut -d':' -f1 infile

然后用sed替换空格:

cut -d':' -f1 infile | sed 's/\([a-z]\) /\ /g'

然后echo没有换行的输出:

echo -n "$(cut -d':' -f1 infile | sed -e 's/\([a-z]\) /\ /g')"

添加缺少的 : 及其后的内容:

echo -n "$(cut -d':' -f1 infile | sed -e 's/\([a-z]\) /\ /g')" | cat - <(echo -n :) | cat - <(cut -d':' -f2 infile)

一个 perl one liner in bash to use \G and \K (similar ) 的想法。

perl -pe 's/\G[^ :]*\K /\ /g' myfile

See this demo at tio.run or a pattern demo at regex101.

这可能对你有用 (GNU sed):

 sed -E ':a;s/^([^: ]*) /\n/;ta;s/\n/\ /g' file

用换行符替换 : 之前的 space,然后用 \ 替换换行符。

使用保留的替代方法 space:

 sed -E 's/:/\n:/;h;s/ /\ /g;G;s/\n.*\n//' file

在第一个 : 上拆分行。

修改前面部分,删除中间部分并添加完整的后面部分。