我是个新手。我有一份文件看起来是:
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"/>我正在执行搜索并替换"fo“标签的位置。我想捕获标签的开头,以及"src“参数。请注意,src标签的位置因行而异!
我已经能够使用以下方法获得我想要的字段:
awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") print $1 " " $i}}' inventory.txt我怎样才能就地替代这个呢?我还想在行的新内容中添加一个字符串。我试过:
awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") print $1 " " $i "misc stuff here"}}' inventory.txt但是,它完全扰乱了结果字符串的顺序,我希望它的形式是:
<fo:external-graphic src="url(images/image1.png)" misc stuff herePS1:进一步澄清我想要的结果:该文件包含字符串,如:
<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"/>我想对这些内容进行处理,并获得如下输出:
<fo:external-graphic src="url(images/image1.png)" _completely new stuff here, till end of string_ />例如:
<fo:external-graphic src="url(images/image1.png)" age="25" sex="M" />我希望结果总是从以下方面开始:
<fo:external-graphic src="url(images/image1.png)"然后是额外的东西,如:
age="25" sex="M" />在最终输出中不需要原始字符串的其他部分。
PS2:我能把这些都打包成gsub吗?据我所知,gsub只提出了两个论点。我试着用一个复杂的表达式来表示替换论点,但它一直失败:
gawk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") gsub($0, "boy band"); {print}}}' inventory.txt > testresPS3:这只是新手的观察,也许我错了。考虑一个包含以下内容的文件:
Donald Trump
Donald Duck
George Bush
Steve Austin搜索以Donald开头的所有行的regexp是:
/^Donald/如果我想用“兵营”替换所有"Donald“,我可以这样做:
gawk -i inplace '{ gsub(/^Donald/, "Barrack"); { print } }' FILENAME如果我想要完全更改包含“”的所有行,我会这样做:
gawk -i inplace '{ gsub(/^Donald.*/, "Barrack"); { print } }' FILENAMEgawk和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"/>目标文件必须更改为。
发布于 2018-11-22 08:56:34
您的尝试是正确的,但假设您的意图仅在以src开头的单词(即$i上)上添加,则只对该字段应用操作,并保留其他字段的原样。
awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) {if ($i ~ "src") $i = $i " misc stuff here"}}1' inventory.txt部件$i = $i " misc stuff here"只在与regex条件匹配的字段上追加字符串。注意删除了print,并在末尾追加了{..}1。这基本上意味着根据{..}内部所做的修改重新构建整个行。由于我们只对某些字段进行修改,其他字段则保持不变。
如果您想重写以src开头的整个字段并附加一些字符串,请使用与gsub()匹配的正则表达式,并在以&表示的匹配文本之后追加字符串。
awk '/<fo:external-graphic.*/ {for (i=1; i<=NF; ++i) { if ($i ~ "src") gsub(/src=\"url([^"]*)\"/, "& new string", $i ) }}1' inventory.txt从OP最近的编辑来看,OP似乎只希望在末尾添加带有新字符串的src字段。其余的字段似乎可以忽略不计。在GNU上使用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请注意,GNU awk直到4.1.2才进行适当的修改,您只需对其进行修改即可。
gawk -i inplace '{...}' inventory.txt对于之前的版本,请使用临时文件。
awk '{...}' inventory.txt > tmpfile && mv tmpfile inventory.txt或者,如果安装了moreutils,请使用sponge来关闭第一个命令的输出,并用最新的命令重新创建文件。
awk '{...}' inventory.txt | sponge inventory.txt从关于这个问题的示例文本中,人们无法识别它是否属于某种标记语言(XML、HTML)。如果它是一种正确的语法感知语言,那么您应该使用一个知道语法的解析器。
发布于 2018-11-22 09:30:11
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_fileEDIT2:用于更改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 '
/^<fo:/ && match($0,/src=.*>/){
$0=substr($0,1,RSTART-1) OFS "new_value_here.." OFS substr($0,RSTART+RLENGTH+1)
}
1
' Input_file在这段代码中,检查从<fo:字符串开始的一行,然后尝试从src=捕获字符串直到/ by match,并在这里用新的字符串替换捕获的文本。
如果您希望将输出保存到Input_file本身中,那么也可以在上面的代码中添加> temp_file && mv temp_file Input_file。
https://stackoverflow.com/questions/53427025
复制相似问题