0

すべての人に、

これに対する解決策を探すのに多くの時間を費やしましたが、見つけることができません。

背景として、何千ものレコードを含むテキスト データベースがあります。各レコードは次のように区切られています。

"0 @nnnnnn@ Xnnn" // 引用符なし

レコードには、独自の行に多くのフィールドがありますが、部分文字列を検索して置換することに興味があるフィールド (スペースに注意してください) :

" 1 X94 User1.faculty.ventura.ca" // 引用符なし

sed を使用して、部分文字列「.faculty.ventura.ca」を「.students.moorpark.ut」に変更し、すべてのレコードに対してグローバルに、行上で他に何も変更しません。

私は否定的な結果で多くのことをテストしました。

これはどのように行うことができますか?

助けてくれてありがとう。ボブ・ペレス (robertperez1957@gmail.com)

4

2 に答える 2

1

私があなたを正しく理解しているなら、あなたはこれを望んでいます:

sed 's/1 X94 \(.*\).faculty.ventura.ca/1 X94 \1.students.moorpark.ut/' mydatabase.file

これにより、フォームのすべてのレコードが に置き換え1 X94 XXXXXX.faculty.ventura.caられ1 X94 XXXXX.students.moorpark.utます。

すべての機能の詳細は次のとおりです。

  • ''スクリプトにスペースやその他の混乱を含めることができます。
  • s/ 代用を意味します
  • 1 X94 \(.*\).faculty.ventura.ca あなたが代用するものです。は、置換で使用するためにその\(.*\)正規表現に何でも保存します
  • 1 X94 \1.students.moorpark.ut あなたが見つけたものを置き換えるものです。\1 は、最初に一致したもので埋められ\(.*\)ます。(これらを 1 行に複数指定すると、次は \2 になります。)
  • 最後/は、完了したことを sed に伝えるだけです。データベースにレコードを区切るための改行がない場合は、/g行ごとにこの変更を複数回行うために、 で終了する必要があります。
  • mydatabase.file は、データベースのファイル名である必要があります。

これは標準出力に出力されることに注意してください。あなたはおそらく追加したいと思うでしょう

> mynewdatabasefile.name

行の最後まで、すべての出力をファイルに保存します。(端末ではあまり役に立ちません。)

コメントごとに編集

に置き換えたい場合は、別の のセットを次のように使用でき1 F94 bperez.students.Napvil.NCCます。1 F94 bperez.JohnSmith.customer\(.*\)

sed 's/1 X94 \(.*\).\(.*\).Napvil.NCC/1 X94 \1.JohnSmith.customer/' 251-2.txt

これは、保存されている 2 つのパラメーターに一致することを除いて、上記と似ています。この例では、は に\1評価されbperez、 に\2評価されstudentsます。に一致\2しますが、式の置換部分では使用しません。これは、保存されたパラメーターをいくつでも使用できます。(sed にはおそらくいくつかの制限がありますが、ヒットするのに十分に複雑な文字列をヒットしたことはありません。) たとえば、sed スクリプトを にすることができ'\(.\) \(...\) \(.*\).\(.*\).\(.*\).\(.*\)/\1 \2 \3.JohnSmith.customer/'、これは \1 = 1、\2 = X94、\3 = になります。 bperez、\4 = Napvil、\5 = NCC であり、\4 と \5 は無視します。ただし、これは実際には最良の答えではありません。実行できることを示すだけです。それはより醜く、またより受容的であるため、最高ではありません。次に、次のような行で検索と置換を行います2 Z12 bperez.a.b.c、これはおそらくあなたが望むものではありません。私が編集に入れた検索クエリは、タスクに合わせて十分に一般的でありながら、可能な限り具体的です。

別の編集!

私が「できるだけ具体的に」と言ったことを知っていますか?.キャラクターが特別なので、そうではありませんでした。実際、私は非常に一般的でした。は.、「ピリオドに一致」ではなく「任意の文字に一致」を意味します。正規表現は「貪欲」で、可能な限り一致するため\(.*\).\(.*\)、常に最初の文字を埋めます\(.*\) (これは、「任意の文字の多くに 0 を取り、後で一致するように保存する」ということです)。使用してみてください:

    sed 's/1 X94 \(.*\)\.\(.*\).Napvil.NCC/1 X94 \1.JohnSmith.customer/' 251-2.txt

そのエクストラ\はエスケープ シーケンスとして機能し、.「任意の文字」から「ピリオドのみ」に変更します。参考までに、私は他の期間をエスケープしない (しかしエスケープする必要がある) ため、技術的に sed は1 X94 XXXX.StdntZNapvilQNCC有効な一致と見なします。任意の文字を意味するため.、Z または Q は適合と見なされます。

于 2013-02-28T23:08:16.320 に答える