web-dev-qa-db-ja.com

コマンドSedを使用せずに文字列を見つけて置き換える方法は?

ご存じのように、sedは文字列を検索して置き換えるのに非常に効率的です。たとえば、「a」を見つけて「b」に置き換えます:sed 's/a/b/g'

sedの代わりに他のコマンドまたはシェルスクリプトでこれを行うことは可能ですか?

これは、sedコマンドを持たないTV用のトリミングされたLinuxシステム用です。したがって、sed 's/a/b/g'. –の代わりに他のコマンドまたはスクリプトを使用する必要があります

16
binghenzq

はい、これを行うにはさまざまな方法があります。 awkPerl、またはbashを使用して、これらのアクティビティを行うこともできます。一般的にはsedはおそらく、これらのタイプのタスクを実行するための最も適切なツールです。

ファイルdata.txtにこのサンプルデータがあるとします。

foo bar 12,300.50
foo bar 2,300.50
abc xyz 1,22,300.50

awk

$ awk '{gsub("foo", "foofoofoo", $0); print}' data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

Perl

$ Perl -pe "s/foo/foofoofoo/g" data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

インライン編集

上記の例では、ファイルを直接変更することもできます。 Perlの例は簡単です。 -iスイッチを追加するだけです。

$ Perl -pie "s/foo/foofoofoo/g" data.txt 

awkの場合、少し直接的ではありませんが、効果は同じです。

$ { rm data.txt && awk '{gsub("foo", "foofoofoo", $0); print}' > data.txt; } < data.txt

このメソッドは、ブレース '{...} `を使用してサブシェルを作成します。

$ { ... } < data.txt

ファイルがサブシェルにリダイレクトされると、そのファイルは削除され、サブシェルSTDINに読み込まれたファイルのコンテンツに対してawkが実行されます。次に、このコンテンツはawkによって処理され、削除したばかりの同じファイル名に書き戻され、効果的に置き換えられます。

12
slm

単一文字置換の古典的な代替手段は tr コマンドであり、ほぼすべてのシステムで使用できるはずです。

$ echo "foobar" | tr a b   
foobbr

trは、sedsedまたはPerlはもちろん)を1文字の置換に使用することは、スレッジハンマーを使用してフライを殺すことに似ているため、実際にはawkよりも優れています。

grepはこのために設計されておらず、入力を変更せず、検索するだけです。

または、一部のシェルの substitution capabilities を使用できます。ここでは、kshzsh、またはbash構文を使用しています。

$ foo="foobar"
$ echo "${foo//a/b}"
foobbr

解決しようとしている問題を正確に説明すると、より具体的な回答が得られます。

13
terdon

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

ex -s -c '%s/a/b/g|x' file
  1. %すべての行を選択

  2. s代替

  3. gグローバル置換

  4. x保存して閉じる

4
Steven Penny

ストリームではなくファイルを使用している場合は、標準のテキストエディタedを使用できます。

printf '%s\n' ',s/a/b/g' w q | ed file.txt

これはどの* nixでも利用できるはずです。 ',s/a/b/g'内のコンマは、edevery行で機能するように指示します(%を使用することもできます。 )、そして残りは標準的な検索と置換です。 wはファイルに書き込む(保存する)ように指示し、qは終了するように指示します。

Sedの-iオプション(および他のツールの同様のオプション)とは異なり、これは実際には一時ファイルでチートするのではなく、ファイルをインプレースで編集することに注意してください。

これをストリームで動作させることは可能ではないと思いますが、edについてはあまり詳しくありません。実際にその機能があるとしても、驚くことはありません(UNIXの哲学はです)。

3
evilsoup

先祖 ed コマンドの使用(ここで-sはクワイエット(サイレント)を意味し、コマンドの前のコンマはすべての行で実行されることを意味します):

[〜#〜] stdout [〜#〜]に印刷するだけ:

ed -s file <<!
,s/a/b/g
,p
q
!

インプレース置換:

ed -s file <<!
,s/a/b/g
w
q
!
2
Gilles Quenot