我有一个 xml 文件,其中有一行包含多次出现的单词。现在我的目标是在找到匹配项后替换第一次出现。例如下面是文件的示例内容:
我想找到 ticket1 并且只想用 Shyam 替换第一次出现的 Ram_Shyam。
{"body": {"storage": {"representation": "storage", "value":
"<table><tbody><tr><th>Sprint</th><th>Story Id</th><th>Summary</th><th>Team Name</th><th colspan=\"1\">Owner</th><th>Code Check-In</th><th colspan=\"1\">Released Story ID</th><th>Released Status</th><th>Story Closed Date</th><th colspan=\"1\">label</th></tr>
<tr><td colspan=\"10\">NEXT</td></tr><tr><td>Sprint 01</td><td><a href=\"https://jira.com/browse/ticket1\">ticket1</a></td><td>summary</td><td>ABC</td><td>Ram_Shyam</td><td>Yes</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Released</td><td>2021-06-16</td><td>None</td></tr><tr><td>Sprint 74</td><td><a href=\"https://jira.com/browse/ticket2\">ticket2</a></td><td>Summary</td><td>ABC</td><td>Ram_Shyam</td><td>No</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Not Released</td><td>2021-06-16</td><td>None</td></tr>
<tr><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td></tr>
</tbody></table>"
}},"space": {"key": "xyz"}, "title": "Releases Tracker","version": {"number": page_version}, "type": "page"}
有人可以指导如何实现吗?
答案 0 :(得分:1)
首先,这个问题组织得不好:
您作为示例提供的“xml”文件似乎是 JSON 对象的一部分,第一部分是 HTML。
“find ticket1”没有明确定义;我们必须猜出你的意思。
“只用...替换第一次出现的...”也不清楚。可以推断您的意思是“在'find ticket1'之后第一次出现”,但这也是一个假设。
即便如此,我们还是可以对问题的意图做出一些猜测。
让我们将 HTML 内容放入一个文件中,以便我们可以在后面的命令中使用它。我将其命名为 file.html
,我们还将使用 shell 变量 $file
来引用它。
cat <<HTML >file.html
<table><tbody><tr><th>Sprint</th><th>Story Id</th><th>Summary</th><th>Team Name</th><th colspan=\"1\">Owner</th><th>Code Check-In</th><th colspan=\"1\">Released Story ID</th><th>Released Status</th><th>Story Closed Date</th><th colspan=\"1\">label</th></tr>
<tr><td colspan=\"10\">NEXT</td></tr><tr><td>Sprint 01</td><td><a href=\"https://jira.com/browse/ticket1\">ticket1</a></td><td>summary</td><td>ABC</td><td>Ram_Shyam</td><td>Yes</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Released</td><td>2021-06-16</td><td>None</td></tr><tr><td>Sprint 74</td><td><a href=\"https://jira.com/browse/ticket2\">ticket2</a></td><td>Summary</td><td>ABC</td><td>Ram_Shyam</td><td>No</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Not Released</td><td>2021-06-16</td><td>None</td></tr>
<tr><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td></tr>
</tbody></table>
HTML
file=file.html
如果可以简单地将“Ram_Shyam”替换为“Shyam”,则此 sed
命令将起作用:
sed -Ee 's/Ram_Shyam/Shyam/' <$file
如果你运行上面的命令,输出也将是一个难以阅读的 HTML 文本流。
为了更容易阅读,请在 STDIN 或给定文件上使用 tidy
命令,如下所示:
tidy -iq --show-errors 0 $file
<!DOCTYPE html>
<html>
<head>
... # rest of of output omitted
</body>
</html>
让我们做一个小别名,让文件的显示更容易:
alias htidy='tidy -iq --show-errors 0'
现在我们只需输入 htidy file.html
即可查看漂亮的 HTML 输出。
这是上面的 sed
输出整理:
sed -Ee 's/Ram_Shyam/Shyam/' <$file | htidy
我们还可以使用 sed
在到达特定行后应用更改。但是,这要求输入是面向行的。因此,以下 sed
命令将应用于管道中 htidy
的输出:
以下 sed
命令将替换 $target
字符串第一次出现后的前 4 行中第一次出现的 $trigger
字符串。
trigger='jira\.com\/browse\/ticket1'
target='Ram_Shyam'
replacement='Shyam'
htidy $file | sed -Ee "/$trigger/,+4s/$target/$replacement/"
如果 target
字符串可能是更大字符串的一部分,例如:"WolfRam"
,那么我们需要在目标字符串周围放置分词符,如下所示:
trigger='jira\.com\/browse\/ticket1'
target='[[:<:]]Ram_Shyam[[:>:]]' # see `man re_format`
replacement='Shyam'
htidy $file | sed -Ee "/$trigger/,+4s/$target/$replacement/"
答案 1 :(得分:1)
使用 GNU awk 将第三个参数设置为 match()
:
$ awk 'match($0,/(.*)(ticket1.*)/,a) { sub(/Ram_Shyam/,"Shyam",a[2]); $0=a[1] a[2] } 1' file
{"body": {"storage": {"representation": "storage", "value":
"<table><tbody><tr><th>Sprint</th><th>Story Id</th><th>Summary</th><th>Team Name</th><th colspan=\"1\">Owner</th><th>Code Check-In</th><th colspan=\"1\">Released Story ID</th><th>Released Status</th><th>Story Closed Date</th><th colspan=\"1\">label</th></tr>
<tr><td colspan=\"10\">NEXT</td></tr><tr><td>Sprint 01</td><td><a href=\"https://jira.com/browse/ticket1\">ticket1</a></td><td>summary</td><td>ABC</td><td>Shyam</td><td>Yes</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Released</td><td>2021-06-16</td><td>None</td></tr><tr><td>Sprint 74</td><td><a href=\"https://jira.com/browse/ticket2\">ticket2</a></td><td>Summary</td><td>ABC</td><td>Ram_Shyam</td><td>No</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Not Released</td><td>2021-06-16</td><td>None</td></tr>
<tr><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td></tr>
</tbody></table>"
}},"space": {"key": "xyz"}, "title": "Releases Tracker","version": {"number": page_version}, "type": "page"}
或任何 awk:
$ awk 'match($0,/ticket1.*/) { tgt=substr($0,RSTART,RLENGTH); sub(/Ram_Shyam/,"Shyam",tgt); $0=substr($0,1,RSTART-1) tgt } 1' file
{"body": {"storage": {"representation": "storage", "value":
"<table><tbody><tr><th>Sprint</th><th>Story Id</th><th>Summary</th><th>Team Name</th><th colspan=\"1\">Owner</th><th>Code Check-In</th><th colspan=\"1\">Released Story ID</th><th>Released Status</th><th>Story Closed Date</th><th colspan=\"1\">label</th></tr>
<tr><td colspan=\"10\">NEXT</td></tr><tr><td>Sprint 01</td><td><a href=\"https://jira.com/browse/ticket1\">ticket1</a></td><td>summary</td><td>ABC</td><td>Shyam</td><td>Yes</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Released</td><td>2021-06-16</td><td>None</td></tr><tr><td>Sprint 74</td><td><a href=\"https://jira.com/browse/ticket2\">ticket2</a></td><td>Summary</td><td>ABC</td><td>Ram_Shyam</td><td>No</td><td><a href=\"https://jira.com/browse/NA\">NA</a></td><td>Not Released</td><td>2021-06-16</td><td>None</td></tr>
<tr><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td><td>Dummy</td></tr>
</tbody></table>"
}},"space": {"key": "xyz"}, "title": "Releases Tracker","version": {"number": page_version}, "type": "page"}