【问题标题】:How to use grep and sed in order to replace the substring after searching some specific string?搜索某些特定字符串后,如何使用 grep 和 sed 替换子字符串?
【发布时间】:2017-06-08 18:10:39
【问题描述】:
我想知道如何使用两个“grep”和“sed”实用程序或其他工具来替换子字符串。我将在下面解释我想要做什么。
我们有包含以下字符串的文件“test.txt”:
A1='AA1', A2='AA2', A3='AA3', A4='AA4', A5{ATTR}='AA5', A6='keyword_A'
使用 grep 搜索 'keyword_A' 后,我想将 A5 的值替换为其他字符串,例如“NEW”。
A1='AA1', A2='AA2', A3='AA3', A4='AA4', A5{ATTR}='NEW', A6='keyword_A'
我尝试使用两个命令,例如
grep keyword_A test.txt | sed -e 's/blabla/blabla/'
在尝试了我所知道的一切之后,我完全放弃了。
请告诉我正确的解决方案。
【问题讨论】:
标签:
linux
string
replace
sed
grep
【解决方案1】:
首先,您永远不需要 grep 和 sed。 Sed 有一个完整的正则表达式搜索引擎,因此它是 grep 的超集。此命令将读取test.txt,更改您指定的行,并在标准输出上打印整个结果:
sed "/keyword_A/s/A5{ATTR}='[A-Z0-9]*'/A5{ATTR}='NEW'/g" < test.txt
如果要将结果存储回文件test.txt,请使用-i(就地编辑)切换到sed:
sed "/keyword_A/s/A5{ATTR}='[A-Z0-9]*'/A5{ATTR}='NEW'/g" -i.bak test.txt
如果您想仅选择指定的行,修改这些行,然后仅将这些行打印到标准输出,请结合使用p(打印)命令和-n(无输出)开关。
sed "/keyword_A/s/A5{ATTR}='[A-Z0-9]*'/A5{ATTR}='NEW'/gp" -n test.txt
【解决方案2】:
使用 grep+sed 总是错误的方法。这是使用 GNU awk 的一种方法:
$ awk '/keyword_A/{ $0=gensub(/(A5({[^}]+})?=\047)[^\047]+/,"\\1NEW",1) } 1' file
A1='AA1', A2='AA2', A3='AA3', A4='AA4', A5{ATTR}='NEW', A6='keyword_A'
【解决方案3】:
使用几个变量,您可以定义关键字和替换(如果它们发生变化):
q="keyword_A"
r="NEW"
然后用sed:
sed -r "s/^(.+\{.+\}=')(.+)('.+"${q}".+)$/\1"${r}"\3/" file
结果:
A1='AA1', A2='AA2', A3='AA3', A4='AA4', A5{ATTR}='NEW', A6='keyword_A'
【解决方案4】:
A5="NEW"
A6="keyword_A"
# with sed
sed "s/='[^']*\(',[[:blank:]]*A6='${A6}'\)/='${A5}\1/" YourFile
# with awk
awk -F "'" -v A5="${A5}" -v A6="${A6}" '
BEGIN { OFS="\047" }
$12 == A6 { $10 = A5; $0 = $0 }
7
' YourFile
- 在字符串末尾更改,用于 sed 并使用
' 作为 awk 中的字段分隔符,而不是传统的空格。
- 假设 awk 版本中没有
' 的值(或需要处理转义方法)
【解决方案5】:
找到sting关键字_A后直接替换第五列即可,如下图:
awk -F, 'BEGIN{OFS=",";}/keyword_A/{$5="A5{ATTR}='"'"NEW"'"'"}1' filename
【解决方案6】:
几个轻微的选择:
sed -r "/keyword_A/s/(A5[^']*')[^']*/\1NEW/"
awk -F"'" '/keyword_A/{$10 = "NEW"}1' OFS="'"
当然,awk 的负面影响是之后您必须重命名新文件。