2 単語に基づいて sed を実行し、行全体を変数に置き換えます。

2 単語に基づいて sed を実行し、行全体を変数に置き換えます。

次のtxtファイルがあります。

1:Ana:apple:08:00:wait
1:Joe:banana:08:30:wait
1:Oscar:orange:08:45:ready
1:Monica:apple:08:50:ready
1:Mark::orange:ready

私が見つけなければなりません最初の行だけ2つの単語が含まれており、「バナナ」と「ちょっと」それからフルライン交換そして$myvar

これまでこのコードを試してみましたが、同時に2つの単語を一致させるのにいくつかの問題があるようです。

sed -i "0,/banana.wait/c\$myvar" myfile

私を助けることができる人のおかげで

答え1

コマンドがおよびを含む行cにのみ影響を与えるには、両方のパターンのいずれかに一致しない行をスキップします。現在の行の編集スクリプトの終わりに分岐する次のコマンドを使用して、これを実行できます。bananawaitb

sed -e '/banana/!b' -e '/wait/!b' -e "c\\$myvar" file

c現在の行が一致しないbananawaitまたは任意の順序で)コマンドをスキップします。

順序が重要な場合(bananawait)を使用してください。

sed -e '/banana.*wait/!b' -e "c\\$myvar" file

banana部分文字列(onlyやnotなど)以外の単語全体を一致させることが重要な場合は、各単語をまたはで囲み、単語のbananas境界が正しく一致することを確認してください。\<...\>\b...\b

二重バックスラッシュを参照してください。これは、二重引用符で囲まれた文字列内に単一のバックスラッシュを挿入する方法です。$では単一のバックスラッシュがエスケープされ、$myvar変数は拡張されません。

これには、改行文字なしでコマンドテキストを入力できるsedGNUなどの実装が必要です。sedc

これはまた、次のように、値のリテラル改行文字が$myvarリテラルバックスラッシュ文字を使用してエスケープされると仮定します。

myvar='hello\
world'

入力データがフィールドを含むレコードで構成されていて、どのフィールドが何で、bananaどのフィールドが重要であるかを確認する場合は、たとえば次のようにwaitレコードを正しく解析できます。awk

value=$myvar awk -F : '$3 == "banana" && $NF == "wait" { $0 = ENVIRON["value"] }; 1' file

これは、最後のフィールドである3番目のフィールドbanana(正規表現部分文字列テストではなく正確な文字列テスト)を明示的にテストし、wait現在のレコードを環境変数に渡された指定された値に置き換えますvalue

答え2

フレームワークの課題:sedはこの問題に対する最善のツールではありません。

Awkでは、順序に関係なく一致を組み合わせることができます/banana/ && /wait/

あるいは、特定のフィールドを正確に一致させることもできます。

awk -F: -v repl="$myvar" -e '$3 == "banana" && $6 == "wait" { $0 = repl } {print}'

関連情報