一部のDokuWikiページをMediaWiki形式に変換するシェルスクリプトを作成しています。その逆に。脚注に問題があります。
DokuWikiには、DokuWikiのデフォルトの脚注マークアップに拡張機能を追加するプラグインがあります。そのうちの1つは、メモに名前を追加して後で再利用できる機能です。たとえば、
徳ウィキ | メディアウィキ |
---|---|
[(FOO>This is a footnote.)] |
<ref name="FOO">This is a footnote.</ref> |
[(BAR>Another note in the same paragraph.)] |
<ref name="BAR">Another note in the same paragraph.</ref> |
そしてsed簡単に見つけて交換できます。 "コメント名"を持つ脚注に関連する私のスクリプトコマンドは次のとおりです。
sed -ri 's@\[\(.*>@<ref name=\"XXX\">@g' dokuwiki-page.txt
sed -ri 's@\)\]@<\/ref>@g' dokuwiki-page.txt
ただし、もちろん名前は保持されず、その名前を持つすべてのコメントに新しい一般コメント名「XXX」を適用するだけです。したがって、上記の例では、結果は次のようになります。
徳ウィキ | メディアウィキ |
---|---|
[(FOO>This is a footnote.)] |
<ref name="XXX">This is a footnote.</ref> |
[(BAR>Another note in the same paragraph.)] |
<ref name="XXX">Another note in the same paragraph.</ref> |
コメント名(例ではFOOとBAR)を維持するのに役立ちます。私は他の解決策を受け入れるだけではありません。sed。
重要事項:
- 脚注文は段落の途中に表示され、脚注名を含む複数の参照は同じ段落に異なる名前で表示されることがあります。 (別名Unixの「非常に長い行」の段落)
- MediaWikiマークアップはHTMLタグ(sumsでいっぱい)が多すぎるため、コマンドを分割して最初のコマンドから置き換え、2番目のコマンドで
[(
置き換えることはできません。タグが誤って交換された可能性があります。>
<
>
- 内部
[(...)]
がないものもあります。代わりに>
inのようです。[(This is a nameless note.)]
[(My_Note_Name>This is a named note.)]
答え1
perl
貪欲ではない反復演算子で正規表現を使用すると、この種の操作ははるかに簡単です。
perl -i -pe 's{\[\((.*?)>(.*?)\)\]}{<ref name="$1">$2</ref>}g' your-file
-i
とは-r
非標準sed
オプションです。-i
実際にはperl
互いに互換性のない方法ですが、いくつかの実装によってコピーされます。
perl
複数sed
の実装とは異なり、行のサイズに制限はなく、NUL文字を処理でき、デフォルトでは入力をバイト単位で処理するため、ユーザーのロケールからテキストにデコードできない入力の問題はありません。
入力の一部にが[(...)]
含まれていない可能性がある場合は、正規表現を調整する必要が>
あります。参照ラベルにw
ord文字(ASCII番号と下線)のみが含まれている場合は、次のようになります。
perl -i -pe 's{\[\((\w+)>(.*?)\)\]}{<ref name="$1">$2</ref>}g' your-file
別の方法は、すべての項目を見つけて[(...)]
別のステップに置き換えることです。
perl -i -pe '
s{\[\(.*?\)\]}{
$& =~ s{\[\((.*?)>(.*)\)\]}{<ref name="$1">$2</ref>}r
}ge' your-file
また、以下を使用して名前のないコメントを変更することもできます<ref>nameless</ref>
。
perl -i -pe '
s{\[\(.*?\)\]}{
$& =~ s{\[\((?:(.*?)>)?(.*)\)\]}{
"<ref" . (defined($1) ? qq( name="$1") : "") . ">$2</ref>"
}re
}ge' your-file
[(...)]
または、含まれていないものと一致することを確認するには、否定予測演算子を使用してください)]
。
perl -i -pe 's{\[\(((?:(?!\)\]).)*?)>((?1))\)\]}{<ref name="$1">$2</ref>}g' your-file
答え2
最終的なSED方法:
私は以下を使って解決策を見つけました:sedと正規表現グループ。
sed -Ei 's@\[\(([[:alnum:]_-]*)>([[:alnum:][:space:].!?:;,@#%$&<>-_]*)\)\]@<ref name=\"\1\">\2<\/ref>@g' dokuwiki-page.txt
説明する:
[(
+letters, numbers, underscores and dashes in any quantity
+>
+letters, numbers, spaces and punctuation
+ で行を検索)]
- グループ1:文字、数字、下線、ダッシュを任意の数だけ使用できます。
- グループ2:文字、数字、スペース、およびほとんどの句読点を使用できます。何らかの理由で
[:punct:]
これはうまくいかず、大きなリストを使うべきです.!?:;,@#%$&<>-_
。 - ここでの秘訣は、
\1
グループを使用または参照できることです\2
。変数に保存するのと同じです。 - 他の項目が含まれているため、
.*
代わりに使用できません。したがって、同じ段落に異なる名前の脚注(別名非常に長い行)がある場合、正規表現には最初の脚注から2番目の脚注の内容の終わりまでのすべての内容が含まれます。本当に台無しだ!([[:alnum:]_-]*)
>
- これらすべてを
<ref name="
++group \1
+">
+group \2
+に置き換えてください</ref>
。- ここでは、周辺コンテンツの交換中に維持したいコンテンツを逆参照して
\1
使用します。\2
- ここでは、周辺コンテンツの交換中に維持したいコンテンツを逆参照して
非常に非常に難しいです!これを行う方法を理解するのに3日かかりました。そして長すぎます。 Perlを選択することをお勧めします。しかし、sedを使うより簡単な方法を知っているなら、私に教えてください。私は学ぶのが大好き!
読書提案:
- ドハティ、D.、&ロビンス、A.(1997)。 SEDとAWK。 (第2版)。オライリー。