SEDを使用してログファイルからテキストを抽出しようとしています。あまり問題なく検索と置換を行うことができます。
sed 's/foo/bar/' mylog.txt
ただし、大文字と小文字を区別しない検索を行いたいです。私がグーグルで調べたところ、コマンドの最後にi
を追加するように見えます:
sed 's/foo/bar/i' mylog.txt
ただし、これによりエラーメッセージが表示されます。
sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'
ここで何が間違っているのですか、どうすれば修正できますか?
明確にするために:OnmacOS-Mojave(10.14)以降-sed
- [〜#〜] bsd [〜#〜] 実装-大文字と小文字を区別しないマッチングをサポートしません-信じがたいですが、本当です。 以前受け入れられた回答 は、それ自体が [〜#〜] gnu [〜#〜] sed
コマンドを示し、コメントに記載されているPerl
ベースのソリューション。
Perlソリューションが外来文字でも動作するようにするには、UTF-8を介して、次のようなものを使用します。
Perl -C -Mutf8 -pe 's/öœ/oo/i' <<< "FÖŒ" # -> "Foo"
-C
は、現在のロケールがUTF-8ベースであると仮定して、ストリームとファイルのUTF-8サポートをオンにします。-Mutf8
は、ソースコードをUTF-8(この場合、-pe
に渡される文字列)として解釈するようPerlに指示します-これは、より詳細な-e 'use utf8;'.
ありがとう、 マークリード(awk
を使用することはオプションではありません、macOS上のawk
(つまり、 BWK awk 、別名 BSD awk )はロケールを完全に認識していないようです-そのtolower()
およびtoupper()
関数は外来文字を無視します(およびsub()
/gsub()
は、大文字小文字を区別しないフラグで始まりません)。
編集者のメモ:このソリューションは、macOSでは動作しません(そのままで)[〜#〜] gnu [〜#〜]sed
。macOSには[〜#〜] bsd [〜#〜]sed
が付属しています。
「I」を大文字にします。
sed 's/foo/bar/I' file
Mac OS X上のsed
の別の回避策は、MacPortsまたはHomeBrewからgsed
をインストールしてから、エイリアスsed='gsed'
。
Macバージョンのsed
は少し制限されているようです。これを回避する1つの方法は、sed
の使用可能なバージョンを持つLinuxコンテナーを使用することです(Docker経由)。
cat your_file.txt | docker run -i busybox /bin/sed -r 's/[0-9]{4}/****/Ig'
sed FAQ は、大文字と小文字を区別しない密接に関連するsearchに対処します。 a)sedの多くのバージョンがフラグをサポートしており、b)sedで行うのが面倒なので、むしろawkまたはPerlを使用する必要があることを指摘しています。
しかし、POSIX sedでそれを行うには、次の3つのオプションを提案します(ここでの置換に適応):
大文字に変換し、元の行をホールドスペースに保存します。ただし、これは置換の場合は機能しません。元のコンテンツが印刷前に復元されるため、大文字と小文字を区別しない一致に基づいて行を挿入または追加する場合にのみ適しています。
おそらく、可能性はFOO
、Foo
、およびfoo
に制限されています。これらは
s/FOO/bar/;s/[Ff]oo/bar/
可能なすべての一致を検索するには、各文字に角括弧式を使用できます。
s/[Ff][Oo][Oo]/bar/
私は同様のニーズがあり、これを思いつきました:
単純にすべてのファイルを見つけるためのこのコマンド:
grep -i -l -r foo ./*
this_Shell.shを除外する(コマンドをthis_Shell.shというスクリプトに入れた場合)テキストfooをbarに置き換えるには:
grep -i -l -r --exclude "this_Shell.sh" foo ./* | tee /dev/fd/2 | while read -r x; do sed -b -i 's/foo/bar/gi' "$x"; done
変更されていないファイルのすべてのタイムスタンプを変更するのが好きではなかったため、この方法を選択しました。 grepの結果をフィードすると、ターゲットテキストを含むファイルのみを見ることができます(したがって、パフォーマンス/速度も向上する可能性があります)
使用する前に、必ずファイルをバックアップしてテストしてください。一部の環境では、スペースが埋め込まれたファイルでは機能しない場合があります。 (?)
最初にパターンマッチングを行う場合、たとえば、
/pattern/s/xx/yy/g
次に、パターンの後にI
を追加します。
/pattern/Is/xx/yy/g
例:
echo Fred | sed '/fred/Is//willma/g'
willma
を返します。 I
なしでは、文字列をそのまま(Fred
)返します。