sed は例外リストに置き換えます。

sed は例外リストに置き換えます。

多くの大容量テキストファイルで文字列を置き換える必要がありますが、珍しい文字列(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

それにもかかわらず、読むよりもまだ簡単になります。この概念は

  • スペースを予約するには、除外リストをお読みください。
  • ファイルの各行に対して、このリストを予約済みスペースに追加します。
  • dankda#nk将来の置換を避けるには、リスト内のすべてのファイルを次のように置き換えます。
  • 次にリストを削除し、すべてを次に置き換え、最後にdanksからmonk削除します。#da#nk

l仕組みの説明は最後に追加されます:loop

問題を指摘してくれたStéphaneに感謝します。dankfoodankこれで問題が解決しました。ところが事件の要件はまだ不明なのですが、ofだけ保護されるからdankdankか、それとも2番目のofが一部で保護されるのでそのまま維持しなければならないのか、それとも範囲を外れるのか。dankmonkdankdankdadankdankdadankdankda

おすすめ記事