一致する文字列が両方の行にある場合にのみ、これらの行を交換する必要があります。
前:
REF*CE*-------------------------
REF*1W*-------------------------
後:
REF*1W*-------------------------
REF*CE*-------------------------
私はこれを試しましたが、うまくいきませんでした:
ed -s testfile.txt <<<$'/REF*CE*/-0,/REF*CE*/+0m/REF*1W*/\nw\nq'
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*-------------------------
より一般的には、任意のpattern1およびpattern2
sed -e :a \
-e "\$!N; s/^\(.*${pattern1}.*\)\n\(.*${pattern2}.*\)/\2\n\1/;ta" \
-e 'P;D' < inputfile
特定の正規表現に一致する2つの(おそらく離れた)行をed
と交換する方法の一般的な解決策:
または、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回実行することで元に戻すことができます。つまり、どちらのパターンが1番目か2番目かは関係ありません。
一致した行をホールドバッファに入れ、次の行を読み取って印刷し、ホールドバッファをパターンバッファと交換して再度印刷することで、目的の効果を得ることができます。
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