2行目を置き換える[閉じる]

2行目を置き換える[閉じる]

yyyy-mm-dd hh:mm:ss下のファイルから最初の項目を除くすべての項目を削除したいと思います。だから基本的に私は行の最初の出現をマークし、残りのすべての重複行を削除したいと思います。正規表現cmdを使用してこれを行うのに役立つ人はいますか?

Will use per-minute statistics
Stats from 2016-06-26   00:00:00 to 2016-06-26  23:59:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:03:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:02:00
6/26/2016       0:03:00

答え1

重複したyyyy-mm-dd行をすべて削除するには

% sed '/^yyyy-mm-dd/,$ { n ; /^yyyy-mm-dd/d }' srcfile
Will use per-minute statistics
Stats from 2016-06-26   00:00:00 to 2016-06-26  23:59:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:03:00
6/26/2016       0:01:00
6/26/2016       0:01:00
6/26/2016       0:02:00
6/26/2016       0:03:00

すべての重複行を削除したい場合は、これは少しハッキング的で非効率的ですが、動作し理解しやすいです。 (2番目のsed | grepを最適化できますが、読みやすくなります。IMHO)。

% sed -n '1,/^yyyy-mm-dd/p' srcfile ; sed '1,/^yyyy-mm-dd/d' srcfile | grep -v ^yyyy-mm-dd | sort -u
Will use per-minute statistics
Stats from 2016-06-26   00:00:00 to 2016-06-26  23:59:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:02:00
6/26/2016       0:03:00

答え2

正しいツールはawkです。簡単な方法でロジックを表現できます。seenパターンが最初に表示されるときに変数を設定し、パターンがすでに表示されている場合は、パターンと一致する行をスキップします。行をスキップしていない場合は印刷してください。

awk '/^yyyy-mm-dd[ \t]+hh:mm:ss$/ {if (seen) next; ++seen}
     1 {print}'

これは短縮できますが、より秘密になります。

awk '!(/^yyyy-mm-dd[ \t]+hh:mm:ss$/ && !(seen++))'

答え3

sed -e '0,/^yyyy-mm-dd\s\+hh:mm:ss$/!{/^yyyy-mm-dd\s\+hh:mm:ss$/d}'

(GNU sed 機能) スコープは0,/pattern/最初のエントリと一致するため、0,/pattern/!ファイルの残りの部分を実行して後続の一致をすべて削除します。{...}

答え4

GNU は正規表現アドレスの数値オフセットをサポートしているため、edファイルの終わりまでの範囲を指定できます。その後、その範囲内の同じ正規表現に一致する行を削除できます。最後に変更されたファイルを作成して終了します。 /pattern/+1$g//d

ed file << EOF
/^yyyy-mm-dd/+1,$ g//d
wq
EOF

または等しく

 printf '/^yyyy-mm-dd/+1,$ g//d\nwq\n' | ed file

関連情報