多くの大容量テキストファイルで文字列を置き換える必要がありますが、珍しい文字列(200項目以上)のリストがあります。たとえば、
# I want to replace every "dank". Except when it comes in the following form:
dankine
dankzwd
nudankip
dankphys
danko.mod
... (The list is 200+ items long)
私の現在の正規表現は次のとおりです。
sed -e "s/dank/monk/g" /path/to/file
ファイルの内容は次のとおりです。
xdankine redankus
dankzwd
danke dankbe
testdank
実行後のファイルの内容は次のとおりです。
xmonkine remonkus
monkzwd
monke monkbe
testmonk
しかし、私は内容が次のようになりたいです。
xdankine remonkus
dankzwd
monke monkbe
testmonk
これはdankineとdankzwdが私の除外リストにあるからです。
ファイルの各行には、複数の可能な代替項目を含めることができます。
どうすればいいですか?
ベストアンサー1
dank
例のように、各行が一度だけ発生する場合は、逆方向アドレスを使用できます。
sed -E '/dankine|dankzwd|nudankip|dankphys|danko\.mod/!s/dank/monk/'
各行が複数回表示される場合は、ファイルの一部にはできない文字を使用できます。たとえば、#
すべてdank
に変更し#
、単語リストをもう一度に変更し、残りを次に変更します#
。monk
sed 's/dank/#/g;s/#ine/dankine/g;s/#zwd/dankzwd/g;s/nu#ip/nudankip/g;s/#phys/dankphys/g;s/#o\.mod/danko.mod/g;s/#/monk/g'
(どんな文字でも表示できる場合は、代わりに改行文字を使用してください)
更新:ファイルから除外リストを読むための新しい要件
ブラックリストをファイルに書き込むexclusion.list
末尾改行を含む(スクリプトはそれを使用して最初のファイルの終わりを検出します):
sed -e '1,/^$/{H;d;}' -e 'G;s/\n/&&/;:loop' -e 's/\(.*da\)\(nk.*\)\(.*\n\1\2\n\)/\1#\2\3/;tloop' -e 's/\n.*//;s/dank/monk/g;s/da#nk/dank/g' exclusion.list file
または、複数行を読む方が簡単になる可能性があるため
sed '1,/^$/{H;d;}
G
s/\n/&&/
:loop
s/\(.*da\)\(nk.*\)\(.*\n\1\2\n\)/\1#\2\3/
tloop
s/\n.*//
s/dank/monk/g
s/da#nk/dank/g' exclusion.list file
それにもかかわらず、読むよりもまだ簡単になります。この概念は
- スペースを予約するには、除外リストをお読みください。
- ファイルの各行に対して、このリストを予約済みスペースに追加します。
dank
da#nk
将来の置換を避けるには、リスト内のすべてのファイルを次のように置き換えます。- 次にリストを削除し、すべてを次に置き換え、最後に
dank
sからmonk
削除します。#
da#nk
l
仕組みの説明は最後に追加されます:loop
。
問題を指摘してくれたStéphaneに感謝します。dankfoodank
これで問題が解決しました。ところが事件の要件はまだ不明なのですが、ofだけ保護されるからdankdank
か、それとも2番目のofが一部で保護されるのでそのまま維持しなければならないのか、それとも範囲を外れるのか。dankmonk
dank
dankda
dankdank
da
dank
dankda