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


16

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

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

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


実際、それは単なる正規表現ベースの置換です。そのようなことを処理することができる任意のツールや言語が同じことを行うことができるであろうが、様々な構文を持ちます:$var=~s/a/b/ggsub(/a/,"b",var)var.gsub(/a/,'b')var.replace(/a/g,'b')preg_replace("/a/","b",$var)regsub -all a b $var。それに加えて、多くのツールと言語はプレーンテキスト文字列の置換を行うこともできます。あなたの質問はなんとなく広範です。
マナトワーク

1
どうして?どのような問題を解決しようとしていますか?
ジル 'SO-悪である停止'

TV用にトリミングされたLinuxシステムには、sedコマンドがありません。そのため、sed 's / a / b / g'の代わりに他のコマンドまたはスクリプトを使用する必要があります。
binghenzq

回答:


12

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

ファイルにこのサンプルデータがあるとします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

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


答えてくれてありがとう、私は次の仕事でそれを試してみますが、「sed」などの一部のコマンドがTVのトリミングされたLinuxシステムに存在しない可能性があるため、うまくいくかどうかわかりません。 、 'grep'などで解決します。
binghenzq

@binghenzq-ファイルをインライン編集する例を追加しました。
slm

-1私はめったに賛成票を投じませんが、この場合、問題のポイントは他のより/同等に複雑で、おそらく依存しているよりも単純な方法であるように見えました。質問がフル* nixマシンインストールの代替案にすぎない場合は、おそらくそうでなければ良い答えを+1するでしょう。
マイケルデュラント

@MichaelDurrant-OPが要求した複雑なインライン編集を追加しました。また、OPはの要件を設定しないで使用してsedいないI. sedのは、このような置換を行うための適切なツールである、と彼は明らかに、より良いので、これらの事は悪いものの、誰かを示し、これらのツールの役割を理解するために求めていますが、非常に示すの教育ですそれらの理由。あまりにも多くの人が知っている人は、理由を説明せずに単に「やらない」と言うので、私はそうです。しかし、少なくともDVの理由についてコメントを残してくれてありがとう。
slm

確かに、私はそれが他のすべての点で素晴​​らしい答えだと思いました。ええ、説明なしで-1が嫌いです。
マイケルデュラント

13

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

$ echo "foobar" | tr a b   
foobbr

trsedこれは、実際にこれよりも優れています。1文字の置換にsed(単独perlまたはawk)を使用することは、スレッジハンマーを使用してハエを殺すようなものです。

grep このために設計されておらず、入力を変更せず、検索のみを行います。

または、一部のシェルの置換機能を使用できます。ここでkshzshまたはbash構文を使用します:

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

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


大文字と小文字を区別し${foo//a/b}ないオプションはありますか?
AlikElzin-kilaka

@ AlikElzin-kilaka私は怖くない。たとえば、次のようなより高度なものを使用するかecho "$foo" | sed 's/a/b/i、文字クラスを指定する必要がありますecho ${foo//[aA]/b}
テルドン

4

ExモードでVimを使用できます:

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

  2. s 代替

  3. g グローバル置換

  4. x 保存して閉じます


まことにありがとうございます。追加するだけで、-cフラグは編集が開始されたときにコマンドを実行し(exはエディターであるため)、-sフラグはフィードバックを無効にするスクリプトモードまたはslient-modeのようなものです。詳細についてはref:ex-vi.sourceforge.net/ex.html
ジミーMGリム

3

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

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

これは、任意の* nixで利用できるはずです。のコンマは、すべての行で動作するよう',s/a/b/g'指示edします(vimに慣れている場合は、これもおなじみです)を使用し、残りは標準の検索および置換です。ファイルを書き込む(保存する)ように指示し、終了するように指示します。%wq

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

これをストリームで動作させることは不可能だと思いますが、それから私はあまり多くのことedを知りませんし、実際にその機能を持っているとしても驚きません(unixの哲学はそれです)。


2

先祖コマンドを使用します(これ-sは、quiet(silent)を意味し、コマンドの前のコンマはすべての行で実行することを意味します)。

STDOUTに印刷するだけです:

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

インプレース置換:

ed -s file <<!
,s/a/b/g
w
q
!
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.