一致する文字列が両方の行にある場合にのみ、行を置き換える必要があります。
今後:
REF*CE*-------------------------
REF*1W*-------------------------
後ろに:
REF*1W*-------------------------
REF*CE*-------------------------
私はこれを試しましたが、うまくいきません。
ed -s testfile.txt <<<$'/REF*CE*/-0,/REF*CE*/+0m/REF*1W*/\nw\nq'
答え1
sed -e :a -e '$!N;s/^\(REF\*CE.*\)\n\(REF\*1W.*\)/\2\n\1/;ta' -e 'P;D' <testfile.txt
- 最後の行にない場合は、次の行を追加します。
- 一致するものがある場合にのみ、現在の行で置き換えが行われます
substring containing pattern 1 + newline + substring containing pattern 2
。置換は2つの部分文字列を反転します。交換後の返品ラベル:a。 - 一致するものがない場合は、パターンスペースをそのまま印刷します。その後、パターン空間を削除し、ループを再開します。
周辺線の例...
In:
XEF*CE*-------------------------
REF*CE*-------------------------
REF*1W*-------------------------
REF*2W*-------------------------
Out:
XEF*CE*-------------------------
REF*1W*-------------------------
REF*CE*-------------------------
REF*2W*-------------------------
より一般的には、すべてのモード1とモード2に適用されます。
sed -e :a \
-e "\$!N; s/^\(.*${pattern1}.*\)\n\(.*${pattern2}.*\)/\2\n\1/;ta" \
-e 'P;D' < inputfile
答え2
特定の正規表現に一致する2行(離れている可能性があります)を置き換える方法の一般的な解決策は次のとおりですed
。
- コピー1行を過ぎて2行目まで。
- 移動する2番目の行は元の最初の行の後に続きます。
- 削除最初の元の行です。
または、ed
編集コマンドを使用します。
/pat1/t/pat2/
?pat2?m/pat1/
?pat1?d
例は次のとおりです。文書
CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
AMT*AU*489.8
REF*6R*00000000002
DTM*472*20160528
CAS*OA*23*306.01
CAS*PR*2*82.29
SVC*HC:99212:25*489.8*101.5**1
AMT*B6*411.43
AMT
最初の行を2番目の行に置き換えたいと思いますCAS
。 pat1
そして^AMT\*AU
これからもpat2
なるでしょう^CAS\*PR
。*
正規表現で文字通り処理されるようにエスケープする必要があります。
変更内容を見やすくするために、以下にコメントしました。XXX
各操作後のファイルの現在位置を示します。
/^AMT\*AU/t/^CAS\*PR/
生産するCLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7 AMT*AU*489.8 <-- Line copied *from* here REF*6R*00000000002 DTM*472*20160528 CAS*OA*23*306.01 CAS*PR*2*82.29 AMT*AU*489.8 <-- Line copied *to* here (XXX) SVC*HC:99212:25*489.8*101.5**1 AMT*B6*411.43
?^CAS\*PR?m/^AMT\*AU/
生産するCLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7 AMT*AU*489.8 CAS*PR*2*82.29 <-- line moved here (XXX) REF*6R*00000000002 DTM*472*20160528 CAS*OA*23*306.01 AMT*AU*489.8 <-- line previous to this deleted SVC*HC:99212:25*489.8*101.5**1 AMT*B6*411.43
?^AMT\*AU?d
生産するCLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7 CAS*PR*2*82.29 <-- the line before this was removed (XXX) REF*6R*00000000002 DTM*472*20160528 CAS*OA*23*306.01 AMT*AU*489.8 SVC*HC:99212:25*489.8*101.5**1 AMT*B6*411.43
覚えやすい「文章」で:
pat1='^AMT\*AU'; pat2='^CAS\*PR'; printf '/%s/t/%s/\n?%s?m/%s/\n?%s?d\nwq\n' "$pat1" "$pat2" "$pat2" "$pat1" "$pat1" | ed -s file
同じタスクを2回目に実行すると、元に戻すことができます。つまり、どのモードが最初のものか2番目のモードかは重要ではありません。
答え3
一致する行を保持バッファに入れ、次の行を読み取って印刷し、保持バッファをパターンバッファに置き換えて再印刷して、目的の効果を得ることができます。
bash-4.3$ sed -n '/^REF\*CE/!p;/^REF\*CE/{h;n;p;x;p}' input.txt
some line here
REF*BB*106497026---------------
REF*1W*723266637---------------
REF*CE*NEW JERSEY--------------
SVC*HC^S5102*78.5*78.5**1------
another line there
答え4
次の簡単な解決策があります。 「XXXX」を含むファイルの行を「YYYY」を含む行に置き換えてから、「XXXX」を含む1行と「YYYY」を含む1行だけを提供するとします。
サンプルファイルは次のとおりです。ssss dddd
aaaa ffff
ddd rrrr
ddddd XXXX
ddddde
ffff
ffff
fff
eeee YYYY
ghghgh
hhhhh
私の "sed"コマンドはsed 's/XXXX/ZZZZ/g;s/YYYY/XXXX/g;s/ZZZZ/YYYY/g'です。 「ZZZZ」文字列がファイルに表示されるべきではないことを覚えておいてください。