仮想IPアドレスを追加したいが、連続した2つの重複行を見つけた後にのみ可能です。
私はLinuxシステムで作業しており、これが私の入力ファイルです。
IP_Remote_Address
Address : 192.168.1.1
IP_Remote_Address
Address : 192.168.1.2
IP_Remote_Address
Address : 192.168.1.3
IP_Remote_Address
IP_Remote_Address
Address : 192.168.1.4
IP_Remote_Address
Address : 192.168.1.5
IP_Remote_Address
Address : 192.168.1.6
IP_Remote_Address
Address : 192.168.1.7
IP_Remote_Address
IP_Remote_Address
Address : 192.168.1.8
私が望む出力:
IP_Remote_Address
Address : 192.168.1.1
IP_Remote_Address
Address : 192.168.1.2
IP_Remote_Address
Address : 192.168.1.3
IP_Remote_Address
Address : NOT_FOUND
IP_Remote_Address
Address : 192.168.1.4
IP_Remote_Address
Address : 192.168.1.5
IP_Remote_Address
Address : 192.168.1.6
IP_Remote_Address
Address : 192.168.1.7
IP_Remote_Address
Address : NOT_FOUND
IP_Remote Address
Address : 192.168.1.8
次の行がありますが、見つかった最初の重複項目のみを置き換えます。
awk '{print $0; if((getline nl) > 0){ print ($0!="IP_Remote_Address" && $0 == nl)? nl=$0"INSERT_NOT_FOUND_ABOVE" : nl }}' file.txt
後でsedを使用して文字列を次のように置き換えることができますINSERT_NOT_FOUND_ABOVE"
。
sed '/INSERT_NOT_FOUND_ABOVE/i Address : NOT_FOUND' file.txt > new_file.txt
私の唯一の問題は、すべての連続重複を検出することができず、最初の重複のみを見つけることです。
答え1
awk
:
awk 'p==$0{print " Address : NOT_FOUND"}{p=$0}1'
やや無邪気なソリューションです。
p==$0
IF p ==現在の行- その後、印刷
not found
- その後、印刷
p=$0
SET p = 現在の行1
: 印刷
連続した重複行を処理します。
指摘したとおり@サンフランシスコ問題のコメントに「おそらく最後のIPもなくなったでしょう?」- UPS。これを考えなければなりません。
だから:
awk -v e='Address : NOT_FOUND' 'p==$0{print e}{p=$0}END{if($1 ~ "IP")print e}1'
- 設定
e
=挿入するテキスト p==$0
IF p ==現在の行- 次に変数を印刷します。
e
- 次に変数を印刷します。
p=$0
SET p = 現在の行END
e
現在の行に以下が含まれているかどうかを印刷するIP
1
: 印刷
ここエラー文字列2回使うので変数として追加しました。 (そしてこの記事では読みやすくするために切り捨てられました)。
答え2
スライドウィンドウを使用してGNU sedでこれを達成する1つの方法は次のとおりです。
解析.sed
# Handle last-line-error
$ { /IP/ s/$/\n Address : NOT_FOUND/; }
# Always keep 2 lines in pattern-space
N
# If the lines are identical
/^([^\n]*)\n\1$/ {
# Add error text
s/\n/\n Address : NOT_FOUND\n/
# Ensure we still only have 2 lines in pattern-space
P
s/[^\n]*\n//
}
# Print line 1 and delete it from pattern-space
P
D
以下は、3つのエラーと最後の行にエラーがある修正済みテストテキストです。
IP_Remote_Address
Address : 192.168.1.1
IP_Remote_Address
Address : 192.168.1.2
IP_Remote_Address
Address : 192.168.1.3
IP_Remote_Address
IP_Remote_Address
IP_Remote_Address
IP_Remote_Address
Address : 192.168.1.4
IP_Remote_Address
Address : 192.168.1.5
IP_Remote_Address
Address : 192.168.1.6
IP_Remote_Address
Address : 192.168.1.7
IP_Remote_Address
IP_Remote_Address
Address : 192.168.1.8
IP_Remote_Address
次のように実行します。
sed -Ef parse.sed infile
または1行で:
<infile sed -E '${/IP/ s/$/\n Address : NOT_FOUND/};N;/^([^\n]*)\n\1$/{s/\n/\n Address : NOT_FOUND\n/;P;s/[^\n]*\n//};P;D'
どちらの場合も出力:
IP_Remote_Address
Address : 192.168.1.1
IP_Remote_Address
Address : 192.168.1.2
IP_Remote_Address
Address : 192.168.1.3
IP_Remote_Address
Address : NOT_FOUND
IP_Remote_Address
Address : NOT_FOUND
IP_Remote_Address
Address : NOT_FOUND
IP_Remote_Address
Address : 192.168.1.4
IP_Remote_Address
Address : 192.168.1.5
IP_Remote_Address
Address : 192.168.1.6
IP_Remote_Address
Address : 192.168.1.7
IP_Remote_Address
Address : NOT_FOUND
IP_Remote_Address
Address : 192.168.1.8
IP_Remote_Address
Address : NOT_FOUND
答え3
拡張正規表現モードでは、ストリームエディタユーティリティsedのGNUバージョンを使用してください。
sed -Ee '
x;1d;G
${/\n\s*IP_/ba;}
/^(.*)\n\1$/{
g;:a;p;c\
Address : NOT_FOUND
b
}
$!s/\n.*//
' file
- 現在の行は記憶空間に入り、前の行はパターン空間に入ります。
- 保留とパターンスペース(つまり、前の行と現在の行)が一致する場合は、対応する行+見つからない行を印刷します。
- 最後の行は /IP_/ で、見つからない行も追加します。