Awk 嵌套条件搜索和就地替换

Awk 嵌套条件搜索和就地替换,awk,Awk,我是一个awk新手。我有一个文件,看起来像: beans and celery beans and oatmeal beans and beans quinoa <fo:external-graphic width="auto" height="auto" content-width="36pt" src="url(file:/C:/Users/xxx/images/tip.svg)"/> <fo:external-graphic src="url(images/i

我是一个awk新手。我有一个文件,看起来像:

beans and celery  
beans and oatmeal  
beans and beans  
quinoa
<fo:external-graphic width="auto" height="auto" content-width="36pt" src="url(file:/C:/Users/xxx/images/tip.svg)"/>
<fo:external-graphic src="url(images/image1.png)" width="6.3in" height="auto" content-width="246px" content-height="322px"/>
最终输出中不需要原始字符串的其他部分

PS2:我可以把这些都打包成一个gsub吗?就我所知,gsub只接受两个参数。我试图为replace参数创建一个复杂的表达式,但始终失败,例如:

gawk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") gsub($0, "boy band"); {print}}}' inventory.txt > testres
搜索以Donald开头的所有行的regexp是:

/^Donald/
如果我想将所有出现的“Donald”替换为“Barrack”,我可以执行以下操作:

awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") print $1 " " $i}}' inventory.txt
gawk -i inplace '{ gsub(/^Donald/, "Barrack"); { print } }' FILENAME
如果我想完全更改包含“Donald”的所有行,我会:

gawk -i inplace '{ gsub(/^Donald.*/, "Barrack"); { print } }' FILENAME
gawk和gsub似乎只替换span或字符串中与给定regexp匹配的任何部分。因此,如果我想完全更改整行,我的regexp应该跨越整行

PS4:只是为了澄清我所期望的解决方案中的任何含糊不清之处。给定以下文件:

<fo:external-graphic width="auto" height="auto" content-width="36pt" src="url(file:/C:/Users/xxx/images/tip.svg)"/>
<fo:external-graphic width="6.3in" height="auto" src="url(images/image1.png)" content-width="246px" content-height="322px"/>
<fo:external-graphic src="url(images/image1.png)" width="6.3in" content-width="246px" content-height="322px"/>

我正在寻找一个awk/gawk解决方案,该解决方案将用以下内容替换此文件:

<fo:external-graphic src="url(file:/C:/Users/xxx/images/tip.svg)" age="25" sex="M" />
<fo:external-graphic src="url(images/image1.png)" age="25" sex="M"/>
<fo:external-graphic src="url(images/image1.png)" age="25" sex="M"/>


必须更改目标文件

您的尝试是正确的,但假设您的意图是仅在以
src
开头的单词上添加,即在
$i
上,则仅对该字段应用操作,并保持其他字段不变

awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") $i = $i " misc stuff here"}}1' inventory.txt
从OP最近的编辑来看,OP似乎只想在末尾添加用新字符串修改的
src
字段。其余字段似乎可以忽略。在GNU
awk
上使用
match()
还有一个额外的优点,即添加第三个参数以将捕获的组存储为

awk -v newstr="age=\"25\" sex=\"M\"" 'match($0, /^(<fo:external-graphic).*(src=\"url([^"]*)\").*(\/>)$/, arr){ print arr[1]" "arr[2]" "newstr""arr[4]  }' file
对于更早的版本,请使用临时文件

awk '{...}' inventory.txt > tmpfile && mv tmpfile inventory.txt
或者,如果安装了
moreutils
,请使用
scribe
从第一个命令中提取输出,并使用最新的命令重新创建文件

awk '{...}' inventory.txt | sponge inventory.txt

从关于这个问题的示例文本中,我们无法识别它是否是某种标记语言(XML、HTML)。如果它是正确的语法感知语言,那么您应该使用了解该语法的解析器。

EDIT3:根据OP的新编辑在此处添加一个代码

awk  '
/ width.*content-width.*src/{
  sub(/ width.*content-width.*src/," src")
  sub(/\/>$/," age=\"25\" sex=\"M\"&")
}
/src.*width/{
  match($0,/src[^)]*/)
  val=substr($0,RSTART,RLENGTH+2)
  sub(/src.*/,"")
  $0=$0 OFS val OFS "age=\"25\" sex=\"M\"/>"
}
1
'  Input_file


EDIT2:要更改OP PS3的完整行,请尝试以下内容

awk '/^Donald/{$0="new_line_value"} 1'  Input_file
new_line_value
new_line_value
George Bush
Steve Austin


编辑:因为OP更改了预期输出,所以现在也根据该输出添加解决方案

awk '/^<fo:external-graphic src=.*/ && match($0,/src=.*\)\"/){$0=substr($0,1,RSTART+RLENGTH) " new_value_bla_bla_here.. />"} 1' Input_file
awk'/^“}1”输入文件


请您尝试以下内容(由于您的预期输出不清楚,所以尚未对其进行彻底测试)

awk'
/^/){
$0=s substr($0,RSTART+RLENGTH+1)的“新值”的substr($0,1,RSTART-1)
}
1.
'输入文件

在这段代码中,检查一行从上述代码中的
temp\u file和&mv temp\u file Input\u file开始。

@Inian它似乎没有更新文件。请查看我更新的问题以查看我期望的最终答案格式!@RavinderSingh13请查看我问题的最新更新!如果您有任何疑问,请告诉我。 Thanks@Inian请查看我的问题的最新更新!如果您有任何疑问,请告诉我。谢谢我上次的更新应该可以解决您的问题。第二行可以。第一行打印出来:。请随时根据我在开始时提供的文件测试您的解决方案question@user1801060,现在检查一下,然后告诉我?我不是che检查字符串
^的条件可能是我的错误。这是我的结果截图:@user1801060,它是否像你想要匹配的所有
src
或任何你想要它做的特定字符串一样?非常努力!第一个不起作用,最后两个起作用。我相信让regexp对所有变体都起作用是个问题。我会看看明天看吧。
<fo:external-graphic src="url(file:/C:/Users/xxx/images/tip.svg)" age="25" sex="M" />
<fo:external-graphic src="url(images/image1.png)" age="25" sex="M"/>
<fo:external-graphic src="url(images/image1.png)" age="25" sex="M"/>
awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") $i = $i " misc stuff here"}}1' inventory.txt
awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) { if ($i ~ "src") gsub(/src=\"url([^"]*)\"/, "& new string", $i ) }}1' inventory.txt
awk -v newstr="age=\"25\" sex=\"M\"" 'match($0, /^(<fo:external-graphic).*(src=\"url([^"]*)\").*(\/>)$/, arr){ print arr[1]" "arr[2]" "newstr""arr[4]  }' file
gawk -i inplace '{...}' inventory.txt
awk '{...}' inventory.txt > tmpfile && mv tmpfile inventory.txt
awk '{...}' inventory.txt | sponge inventory.txt
awk  '
/ width.*content-width.*src/{
  sub(/ width.*content-width.*src/," src")
  sub(/\/>$/," age=\"25\" sex=\"M\"&")
}
/src.*width/{
  match($0,/src[^)]*/)
  val=substr($0,RSTART,RLENGTH+2)
  sub(/src.*/,"")
  $0=$0 OFS val OFS "age=\"25\" sex=\"M\"/>"
}
1
'  Input_file
awk '/^Donald/{$0="new_line_value"} 1'  Input_file
new_line_value
new_line_value
George Bush
Steve Austin
awk '/^<fo:external-graphic src=.*/ && match($0,/src=.*\)\"/){$0=substr($0,1,RSTART+RLENGTH) " new_value_bla_bla_here.. />"} 1' Input_file
awk '
/^<fo:/ && match($0,/src=.*>/){
  $0=substr($0,1,RSTART-1) OFS "new_value_here.." OFS substr($0,RSTART+RLENGTH+1)
}
1
'  Input_file