Text-Processing

用正則表達式替換文件中的(一個或)兩個不同的模式

  • December 3, 2020

假設一個input.txt文件包含多個字元串,如下所示:

[[foo>a|a]]
[[foo>b|b]]
[[foo>c|c]]

我想替換為:

:foo:`a`
:foo:`b`
:foo:`c`

sed我想我可以用or來實現這個結果rg(我從未使用過awk)。

但此文件還包含其他字元串,如下所示:

[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]

我想替換為:

:foo:`d <a>`
:foo:`e <b> `
:foo:`f <c>`

我所有的嘗試都失敗了,因為我不知道如何同時處理兩種不同的模式。

你知道一些方法來實現後者的結果(順便說一句,前者)?

通過環視,您可以檢查周圍的字元串|是否相同。例如:

$ cat ip.txt 
[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]

# same as: rg -NP '\[\[([^>]+)>([^|]+)\|(?!\2])([^|]+)]]' -r ':$1:`$3 <$2>`'
$ perl -pe 's/\[\[([^>]+)>([^|]+)\|(?!\2])([^|]+)]]/:$1:`$3 <$2>`/' ip.txt 
:foo:`d <a>`
:foo:`e <b>`
:foo:`f <c>`

(?!\2])是一個否定的前瞻斷言,以確保周圍的字元串|不同。

要實現這兩者,您可以在帶有e標誌的替換部分中使用 Perl 程式碼。

$ cat ip.txt
[[foo>a|a]]
[[foo>b|b]]
[[foo>c|c]]

[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]

$ perl -pe 's/\[\[([^>]+)>([^|]+)\|([^|]+)]]/":$1:`$3" . ($2 eq $3 ? "`" : " <$2>`")/e' ip.txt 
:foo:`a`
:foo:`b`
:foo:`c`

:foo:`d <a>`
:foo:`e <b>`
:foo:`f <c>`

在這裡,($2 eq $3 ? "" : " <$2>")將根據周圍的字元串是否|相同來選擇字元串。

使用標準sed 語法:

sed '
 s/^\[\[\(.*\)&gt;\(.*\)|\2\]\]$/:\1:`\2`/; t
 s/^\[\[\(.*\)&gt;\(.*\)|\(.*\)\]\]$/:\1:`\3 &lt;\2&gt;`/'

引用自:https://unix.stackexchange.com/questions/622726