
次のファイルがあります(========
実際にはファイルに存在します)。
start ======== id: 5713
start ======== id: 5911
start ======== id: 5911
end ========= id: 5911
start ======== id: 6111
end ========= id: 5713
start ======== id: 31117
start
同じIDを持つそれぞれend
。
上記の例に基づいて、出力は次のようになります。
start ======== id: 5911
start ======== id: 6111
start ======== id: 31117
bash
、、awk
...でsed
これを行う方法は?
答え1
すべてのUnixシステム上のすべてのシェルでawkを使用すると、入力にある数のペアのない開始および/または終了ステートメントが印刷されます。
$ cat tst.awk
$1 == "start" { beg[$NF] = $0; delta = 1 }
$1 == "end" { end[$NF] = $0; delta = -1 }
{ cnt[$NF] += delta }
END {
for ( key in cnt ) {
for (i=1; i<=cnt[key]; i++) {
print beg[key]
}
for (i=-1; i>=cnt[key]; i--) {
print end[key]
}
}
}
$ awk -f tst.awk file
start ======== id: 5911
start ======== id: 6111
start ======== id: 31117
より良いデモンストレーションのために、より包括的な入力例を使用してください。
$ cat file
start ======== id: 5713
start ======== id: 5911
start ======== id: 5911
start ======== id: 5911
end ========= id: 5911
start ======== id: 6111
end ========= id: 5713
end ========= id: 5713
start ======== id: 31117
$ awk -f tst.awk file
end ========= id: 5713
start ======== id: 5911
start ======== id: 5911
start ======== id: 6111
start ======== id: 31117
答え2
sedとnlを入力して並べ替えます。
nl <filename> -s ":"|sort -t ":" -k 3 -k 2 | sed -n ":x s/\n[0-9 ]*$//;/end[^\n]*$/{N;bx};s/\(.*\)[ 0-9]*:end .*id:\( [0-9]*\).*\n.*start.*id:\2[^0-9]*$/\1/;tx;s/\n$//;/start/{P;D};/^[ 0-9]*:end[^\n]*/{s/\n[0-9:]*$/$/;N;bx};/start/P;/end/P;" | sort -n| sed "s/[ 0-9]*://"
nl tt -s ":"|sort -t ":" -k 3 -k 2 | sed -n ":x s/\n[0-9 ]*$//;/end[^\n]*$/{N;bx};s/\(.*\)[ 0-9]*:end .*id:\( [0-9]*\).*\n.*start.*id:\2[^0-9]*$/\1/;tx;s/\n$//;/start/{P;D};/^[ 0-9]*:end[^\n]*/{s/\n[0-9:]*$/$/;N;bx};/start/P;/end/P;" | sort -n| sed "s/[ 0-9]*://"
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5911
start ======== id: 6111
end ======== id: 31117
順序が重要でない場合(両端に出発線がある場合):
sort <filename> -t ":" -k 2|sed -e '/end/{N;d;}
start ======== id: 31117
start ======== id: 5911
start ======== id: 6111
これが良いです(修正が必要ですが動作します)。
sort <filename> -t ":" -k 2 | sed -n ":x ;/end[^\n]*$/{N;bx};s/\(.*\)end .*id:\( [0-9]*\).*start.*id:\2[^0-9]*$/\1/;tx;s/\n$//;/start/{P;D};/^end[^\n]*/{s/\n$/$/;N;bx};/start/P;/end/P"
cat tt
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
dggdgtfZZ
start ======== id: 5713
start ======== id: 5713
start ======== id: 5911
start ======== id: 5911
end ========= id: 5911
start ======== id: 6111
end ========= id: 5713
end ========= id: 5713
end ========= id: 5713
end ========= id: 5713
end ========= id: 5713
start ======== id: 31117
end ======== id: 31117
end ======== id: 31117
sort -t ":" -k 2 tt| sed -n ":x ;/end[^\n]*$/{N;bx};s/\(.*\)end .*id:\( [0-9]*\).*start.*id:\2[^0-9]*$/\1/;tx;s/\n$//;/start/{P;D};/^end[^\n]*/{s/\n$/$/;N;bx};/start/P;/end/P"
end ======== id: 31117
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5713
start ======== id: 5911
start ======== id: 6111