web-dev-qa-db-ja.com

1つの式で複数の針を1つの単語で検索して置き換える方法は?

テキストファイルがあると仮定します。

foo fnord bar
bizz foo poit

そして今、「foo」と「bar」の両方を「narf」に置き換えたいと思います。

私は使用できることを知っています:

 sed -e 's/foo/narf/g' -e 's/bar/narf/g' fileName

それでも、1つの式で両方の針に一致するように正規表現に指示するOR演算子を使用したいと思います。

いくつかのマニュアルを読んで、パイプは自分のニーズに合うはずだと思いますが、試しました

sed -e 's/foo|bar/narf/g' -i fileName

そしてそれは機能せず、エラーをスローすることすらありませんでした。

ここで何が悪いのですか?

8
k0pernikus

拡張正規表現構文には-rオプションを使用します。

sed -r -e 's/foo|bar/narf/g'

それ以外の場合は、論理和を\|としてエスケープします。

sed -e 's/foo\|bar/narf/g'
10

正規表現 構文には多くのバリエーションがあります。正規表現を備えたUNIXの世界で最初のツールには、正規表現の完全な機能はありませんでした。文字セット([…]および.)、繰り返し(*)および行アンカーのみ(^および$)。 基本的な正規表現 これらの演算子のみがあります。 Sedは昔ながらのツールであり、基本的な正規表現を使用します。

多くのsed実装には、完全な正規表現マッチングのための拡張機能があります。文字|はそれ自体を表すため、交互に使用する場合は\|を、グループ化する場合は同様に\(\)を使用する必要があります。 POSIX標準\|基本正規表現 でサポートされることを義務付けておらず、一部のシステム(例 OpenBSD )はサポートすることに注意してくださいそれを持っていません。

Sedの一部のバージョンには 拡張正規表現 に切り替えるオプションがあります。ここで、(…)はグループ化に使用され、|は代替に使用されます。 GNU sed(つまり、LinuxまたはCygwinの場合)または Busybox の場合、-rオプションを渡します。 FreeBSD または- [〜#〜] osx [〜#〜]-Eオプションを渡します。

Sedに交替がない場合は、代わりにawkを呼び出すことができます。 [〜#〜] posix [〜#〜] で義務付けられていますが、このタスクは少し冗長であり、後方参照はサポートされていません。

awk '{gsub(/foo|bar/, "narf")}' <fileName.old >fileName.new

ちなみに、GNUとBusyboxsedのみがファイルの置き換えをサポートしています。Awkと他のバージョンのsedはサポートしていません。 `cut`にファイルを変更させることはできますか? ?

Perlを使用している場合は、テキスト処理のワンライナーで、1つのツールですべての方法を実行できるので便利です。 sed、awkなどで簡単なことのほとんどはPerlでそれほど難しくはなく、単一の(複雑な場合)ツールを学ぶことで逃げることができます。

Perl -i -pe 's/foo|bar/narf/g' fileName

VimはExモードで使用できます。

ex -sc '%s/\vPA|QU/RO/g|x' file
  1. %すべての行を選択

  2. s代替

  3. \v魔法をオンにする

  4. gグローバル置換

  5. x保存して閉じる

0
Steven Penny