正規表現を使用して、ファイル内の1つまたは2つの異なるパターンを置き換えます。

正規表現を使用して、ファイル内の1つまたは2つの異なるパターンを置き換えます。

input.txtファイルに次のような複数の文字列が含まれているとします。

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

私は次のように変更したい:

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

私はsedこの結果を使用または達成できると思いますrg(私はそれを使用したことがありませんawk)。

ただし、ファイルには次のような他の文字列も含まれています。

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

私は次のように変更したい:

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

2つの異なるモードを同時に処理する方法がわからないため、すべての試みは失敗しました。

後者の結果(そして前者の結果)を得るためのいくつかの方法を知っていますか?

答え1

標準sed 構文を使用してください。

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

答え2

周囲を見て、周囲の文字列が|同じであることを確認できます。たとえば、

$ 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])|周囲の文字列が異なることを確認するための否定的な予測アサーションです。


両方を達成するには、代替セクションのフラグでPerlコードを使用できますe

$ 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>`")|

答え3

これを2〜3つの別々の部分に分けることができるようです。最初に squeeze( -s) し、一部の文字を に置き換えて出力のtr「概要」を生成し、次に a を使用してsed2 つの文字が一致する場合に 1 つと 2 つの文字が一致しないときに 2 つの別々の置換を作成します。

< file tr -s '[<>|]' ':::``' | sed -E 's/(.)`\1`/`\1`/; s/([^:])`(.)`/`\2 <\1>`/'

テスト:

$ cat file
[[foo>a|a]]
[[foo>b|b]]
[[foo>c|c]]
[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]

$ <file tr -s '[<>|]' ':::``' | sed -E 's/(.)`\1`/`\1`/;s/([^:])`(.)`/`\2 <\1>`/' 
:foo:`a`
:foo:`b`
:foo:`c`
:foo:`d <a>`
:foo:`e <b>`
:foo:`f <c>`

答え4

awk与えられた2種類の処理を管理するために使用されます。

awk -F'\\[\\[|\\]\\]|>|\\|' '{
    print $1, $2, "`" ($3==$4? $3 : $4" <"$3">") "`";
}' OFS=':' infile

テスト入力:

[[foo>a|a]]
[[foo>bb|bb]]
[[foo>c|ccc]]
[[foo>aaaa|d]]
[[foo>b|ddd]]
[[foo>cccc|fff]]

出力:

:foo:`a`
:foo:`bb`
:foo:`ccc <c>`
:foo:`d <aaaa>`
:foo:`ddd <b>`
:foo:`fff <cccc>`

関連情報