次の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
にのみ影響を与えるには、両方のパターンのいずれかに一致しない行をスキップします。現在の行の編集スクリプトの終わりに分岐する次のコマンドを使用して、これを実行できます。banana
wait
b
sed -e '/banana/!b' -e '/wait/!b' -e "c\\$myvar" file
c
現在の行が一致しないbanana
(wait
または任意の順序で)コマンドをスキップします。
順序が重要な場合(banana
前wait
)を使用してください。
sed -e '/banana.*wait/!b' -e "c\\$myvar" file
banana
部分文字列(onlyやnotなど)以外の単語全体を一致させることが重要な場合は、各単語をまたはで囲み、単語のbananas
境界が正しく一致することを確認してください。\<...\>
\b...\b
二重バックスラッシュを参照してください。これは、二重引用符で囲まれた文字列内に単一のバックスラッシュを挿入する方法です。$
では単一のバックスラッシュがエスケープされ、$myvar
変数は拡張されません。
これには、改行文字なしでコマンドテキストを入力できるsed
GNUなどの実装が必要です。sed
c
これはまた、次のように、値のリテラル改行文字が$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}'