URLを含むタグが複数回表示される大きなテキストファイルがあります。
[tag]https://example.com/222389/link/11835457224168404[/tag]
次のようにラベル形式を再指定する必要があります。
[new-tag]11835457224168404[/new-tag]
("link"("id")の後ろのURL部分のみをキャプチャし、タグを "new-tag"に変更します。)
- 各行には複数のラベルを含めることができます。
- タグの場所は一定ではありません。ファイル全体でランダムに表示されます。
- タグの内容の先頭にスペース(「http」)がある可能性があります。 「http://」または「https://」を使用し、時には「www」も使用します。
タグの末尾(「id」の後ろ)に、次のように内容や空白がある場合があります。
[tag]https://example.com/222389/link/11835457224168404/qwertyiop[/tag]
または
[tag]https://example.com/222389/link/11835457224168404?link=11835457224168401 [/tag]
場合によっては、([/tag]または「http」を閉じずに)単独で表示される「[tag]」を無視する必要があります。
sedまたは代替を使用してこれをどのように実行できますか?
答え1
戦略
正規表現を書くことは可能ですが、いいえ複数文字の文字列を一致させると複雑になる可能性があります。[tag]
合計を[/tag]
単一文字に変換するトリックを使用してから、否定文字クラスを使用します。このスクリプトでは、コントロール-aとコントロール-bを使用します。これは批判的これらの文字はファイルに表示されません。これらは入力するのが難しいので、いくつかの変数を開くタグと閉じるタグとしてs
使用します。閉じるタグではなく一連の文字を表すe
ために使用します。notend
#!/bin/bash
s=$'\001' # control-a, for the start tag
e=$'\002' # control-b, for the end tag
notend="[^$e]*" # expression for not the end tag.
# Program, Change the tags into single characters
# change matched pairs of tags into new form
# convert any unmatched tags back to original form
prog='
s:\[tag]:'"$s"':g
s:\[/tag]:'"$e"':g
s:'"$s$notend"'/link/\([0-9]*\)'"$notend$e"':[new-tag]\1[/newtag]:g
s:'"$s"':[tag]:g
s:'"$e"':[/tag]:g'
# run sed, passing any parameters
sed -e "$prog" "$@"
使用法
このスクリプトを保存して実行可能にした後、実行してデータファイルを引数として渡し、出力を一時ファイルにリダイレクトします。一時ファイルを確認してください。