
Word1 Word2 Word3
テキストファイルがありますが、テキストファイルのすべてのインスタンスを検索しますWord4 Word2 Word5
。Word2は不明な文字列ですが、残りの単語は既知です。
私が今まで試したことは次のとおりです。
文字列がありますが、(...) foobarfoo (...)
これを次のように変更したいと思います。(...) hatbarcar (...)
sed -i 's/foo.*foo/hat.*car/g' data.txt
しかし、私が得た結果は
(...) hat.*car (...)
したがって、ワイルドカードは私が望む単語文字列を見つけることですが、同じワイルドカードを使用して古い文字列を置き換える文字列を作成したいと思います。
これは可能ですか/誰でも提案がありますか?
答え1
問題は
sed -i 's/foo\(.*\)foo/hat\1car/g'
アプローチは貪欲なfooxfoo fooyfoo
asに変更することです。hatxfoo fooycar
.*
perl
代わりに、貪欲ではない演算子を使用できます.*?
。
perl -i -pe 's/foo(.*?)foo/hat$1car/g'
(これは移植性が高いという利点もあります。-i
多くの実装で提供されていますが、perl
多くの実装で使用することはできませんsed
(使用可能であっても、誰もが同じように解釈するわけではありません)。
環境ではなくGNUを使用すると、次のことができますsed
。$POSIXLY_CORRECT
sed -i 's/foo/\n/g;s/\n\([^\n]*\)\n/hat\1car/g;s/\n/foo/g'
つまり、foo
貪欲な同等性を達成するために使用できるように、行に現れない文字(行区切り文字)に置き換えてください。\n
[^\n]*
環境にPOSIXLY_CORRECTがある場合、[^\n]
POSIX以外のすべての文字は一致し、改行以外の文字は一致\
しません。n
いつでも次のことができます。
(unset -v POSIXLY_CORRECT; exec sed...)
POSIXLY_CORRECT が設定された環境でスクリプトが動作し続けたい場合。
答え2
の代替文字列s/PATTERN/REPLACEMENT/
は正規表現ではありません。
あなたはできるでしょう捕獲必要に応じて、交換に使用できるパターンのポイントと一致するもの:
sed -r 's/foo(.*)foo/hat\1car/g' file
foo
これにより、同じ行で2回発生する内容をキャプチャし、間にhat
ビットを挿入しますcar
。\1
「最初の括弧にキャプチャした内容を挿入してください」と表示されます。
これは.*
「貪欲的」なのでがある場合foobarfoofoobarfoo
ではなく\1
なります。barfoofoobar
bar
答え3
sedを使用すると、交換の交換部分で参照できるキャプチャグループを使用し\(
て\)
作成できます。\1
sed 's/foo\(.*\)foo/hat\1car/g'