AWK - 替换不以特殊符号开头的单词

发布于 2024-11-08 06:27:56 字数 427 浏览 0 评论 0原文

我尝试将这一行:

(ModuleEins = WertA | ${ModuleEins} = WertB | ModuleEins = WertB)

翻译为这一行:

(${ModuleEins}= WertA | ${ModuleEins}= WertB | ${ModuleEins}= WertB)

但我无法让它工作。

我有一个复杂的 awk 脚本,我在循环内运行替换语句。

例如 awk '{ sub( "ModuleEins", "${ModuleEins}", $0 ); print, $0 }'

我不知道如何在 awk 中替换不以特殊字符开头的单词。

(?!{)ModuleEins(?!}) <- 这个想法我无法在 awk 中使用。

I try to translate this line:

(ModuleEins = WertA | ${ModuleEins} = WertB | ModuleEins = WertB)

to this line:

(${ModuleEins}= WertA | ${ModuleEins}= WertB | ${ModuleEins}= WertB)

but i don't get it to work.

i have a complex awk script where i run a replacement statement inside a loop.

e.g. awk '{ sub( "ModuleEins", "${ModuleEins}", $0 ); print, $0 }'

i have no idea how to replace in awk a word which not begin with special characters.

(?!{)ModuleEins(?!}) <- This idea i don't get to work inside awk.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

这是一个脆弱的解决方案,但准确地回答了您的问题。

请注意,我

  1. 将 sub(...) 更改为 gsub
  2. 删除了
    ',' 之后 print
  3. 将搜索目标更改为正则表达式 /[^{]ModuleEins[^}]/
  4. 并添加了 '&'捕获 reg exp 的第一个字符,其中 [^{] 是脆弱性所在。

代码

print -- '(ModuleEins = WertA | ${ModuleEins} = WertB | ModuleEins = WertB)' \
| awk '{ gsub( /[^{]ModuleEins[^}]/, "&${ModuleEins}", $0 ); print $0 }'

输出

(ModuleEins ${ModuleEins}= WertA | ${ModuleEins} = WertB | ModuleEins ${ModuleEins}= WertB)

我希望这会有所帮助。

PS,由于您似乎是新用户,如果您得到的答案对您有帮助,请记住将其标记为已接受,和/或给它 +(或 -)作为有用的答案。

This is a brittle solution but exactly answers your question.

Note that I

  1. changed sub(...) to gsub
  2. removed the
    ',' after print
  3. changed the search target to a regular expression /[^{]ModuleEins[^}]/
  4. and added a '&' to capture the first char of the reg exp, which with the [^{] is where the brittleness comes in.

code

print -- '(ModuleEins = WertA | ${ModuleEins} = WertB | ModuleEins = WertB)' \
| awk '{ gsub( /[^{]ModuleEins[^}]/, "&${ModuleEins}", $0 ); print $0 }'

output

(ModuleEins ${ModuleEins}= WertA | ${ModuleEins} = WertB | ModuleEins ${ModuleEins}= WertB)

I hope this helps.

P.S. as you appear to be a new user, if you get an answer that helps you please remember to mark it as accepted, and/or give it a + (or -) as a useful answer.

撩动你心 2024-11-15 06:27:56

感谢您的帮助!

@shellter 子模式 [^{]ModuleEins[^}] 对我不起作用,因为 [^{] 是除 { 之外的符号>。如果我有 "(ModuleEins=value)" ,结果将是 "${ModuleEins}value)" 而不是 "(${ModuleEins}=value )”。这对我来说是错误的。

我在我的 awk 脚本中尝试了 Glenn jackman 的想法并让它发挥作用:

gsub( "\\$", "\\$", $0 )

"echo \""$0" \" | perl -pe 's/(?

gsub( "\\\\\\$", "$", $0 )

ps: 抱歉我还不能投票 -.-

Thanks for help!

@shellter The sub pattern [^{]ModuleEins[^}] would not work for me, because [^{] is a symbol except {. If i have "(ModuleEins=value)" than the result would be "${ModuleEins}value)" and not "(${ModuleEins}=value)". This is for me wrong.

i tried the idea from glenn jackman inside my awk script and get it to work:

gsub( "\\$", "\\$", $0 )

"echo \""$0"\" | perl -pe 's/(?<!{)"part[i]"/\\${"part[i]"}/g'" |& getline $0

gsub( "\\\\\\$", "$", $0 )

ps: sorry i can't vote yet -.-

千鲤 2024-11-15 06:27:56

Perl 正则表达式比 awk 的更好:

 perl -pe 's/(?<!\${)ModuleEins/\${
amp;}/g'

Perl regular expressions are better than awk's here:

 perl -pe 's/(?<!\${)ModuleEins/\${
amp;}/g'
ら栖息 2024-11-15 06:27:56
sed -e 's/(ModuleEins/(${ModuleEins}/g' -e 's/| ModuleEins/| ${ModuleEins}/g'
sed -e 's/(ModuleEins/(${ModuleEins}/g' -e 's/| ModuleEins/| ${ModuleEins}/g'
浅沫记忆 2024-11-15 06:27:56

下面的解决方案是蛮力的,但很容易理解并且非常强大......首先 gsub 将“${ModuleEins}”更改为“ModuleEins”,然后更改所有“ModuleEins”。需要使用“\”转义某些字符,因为 gsub 的第一个参数是扩展正则表达式。在这个迷你语言中,字符“$”、“{”和“}”默认是元字符,并由 gsub 解释为具有特殊含义。

$ x='(ModuleEins = WertA | ${ModuleEins} = WertB | ModuleEins = WertB)'
$ echo $x | awk '{ gsub(/\$\{ModuleEins\}/, "ModuleEins"); gsub(/ModuleEins/, "${ModuleEins}") } 1'
(${ModuleEins} = WertA | ${ModuleEins} = WertB | ${ModuleEins} = WertB)

SED 实现可能是实现简洁性的更好方法:

$ echo $x | sed 's/\${ModuleEins}/ModuleEins/g; s/ModuleEins/${ModuleEins}/g'
(${ModuleEins} = WertA | ${ModuleEins} = WertB | ${ModuleEins} = WertB)

请注意,上面的转义规则有所不同,因为 AWK 使用扩展正则表达式作为搜索模式,而 SED 使用基本/传统正则表达式。两种正则表达式语言之间的差异与元字符的转义有关,egrep(3) 手册中对此进行了描述(搜索“基本正则表达式与扩展正则表达式”)。

The following solution is brute-force, but easy to understand and pretty robust... First gsub to change "${ModuleEins}" to "ModuleEins", then change all the "ModuleEins". Using "\" to escape certain characters is required because the first parameter to gsub is an Extended Regular Expression. In this mini-language, the characters "$", "{" and "}" are meta-characters by default and are interpreted by gsub with special meaning.

$ x='(ModuleEins = WertA | ${ModuleEins} = WertB | ModuleEins = WertB)'
$ echo $x | awk '{ gsub(/\$\{ModuleEins\}/, "ModuleEins"); gsub(/ModuleEins/, "${ModuleEins}") } 1'
(${ModuleEins} = WertA | ${ModuleEins} = WertB | ${ModuleEins} = WertB)

A SED implementation might be the better way to go for its conciseness:

$ echo $x | sed 's/\${ModuleEins}/ModuleEins/g; s/ModuleEins/${ModuleEins}/g'
(${ModuleEins} = WertA | ${ModuleEins} = WertB | ${ModuleEins} = WertB)

Note that the escaping rules are different in the above as AWK uses Extended Regular Expressions for the search pattern and SED uses Basic/Traditional Regular Expressions. The difference between the two regular expressions language have to do with escaping of meta-characters, and such is described in the egrep(3) manual (search for "Basic vs Extended Regular Expressions").

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文