キャリッジリターン(\ r)を含む行のすべてではありませんが、ほとんど削除

キャリッジリターン(\ r)を含む行のすべてではありませんが、ほとんど削除

キャリッジリターン(\ r)を含むステータス行を出力しすぎるプロセスがあります。パイピングにより、これらすべてのステータスバーをフィルタリングできます。

sed '/\r/d' 

代わりに、3行を除くすべての行をフィルタリングしたいと思います。標準のUnixツール(awk?)を使用してこれを実行できますか?それともスクリプトが必要ですか? CRなしの行は変更されていないままにしてください。

与えられた出力:

$ (printf '%s\n' {1..10};   printf  '%s\r\n' {1..10}; printf '%s\n' {1..10};)  | cat -v
1
2
3
4
5
6
7
8
9
10
1^M
2^M
3^M
4^M
5^M
6^M
7^M
8^M
9^M
10^M
1
2
3
4
5
6
7
8
9
10

希望の出力(または他のパターン):

1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10

答え1

$ awk '!(/\r$/ && ((++c)%3 != 1))' file | cat -v
1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10

元の答え:

awkを使うと必要なのはこれだけです。

awk -v RS='\r' '{ORS=(NR%10000 ? "" : RS)} 1'

たとえば、入力として使用する場合:

$ printf '%s\r\n' {1..10} | cat -v
1^M
2^M
3^M
4^M
5^M
6^M
7^M
8^M
9^M
10^M

3つを除いてすべて削除\r

$ printf '%s\r\n' {1..10} | awk -v RS='\r' '{ORS=(NR%3 ? "" : RS)} 1' | cat -v
1
2
3^M
4
5
6^M
7
8
9^M
10

答え2

を使用して計算GNU sedに予約されたスペースを使用します。

sed -E '
  /\r$/{
    G;/\n$/P
    s/.*\n/./
    /.{3}/z;x;d
  }
' file

を使用してawk変数cを3に達したときにリセットされるループカウンタとして使用します。

awk '
!/\r$/ || !c++
c==3{c=0}
' file

\rキャリッジリターン()文字が表示されるたびに、改行()で区切られたレコードの終わりに発生すると仮定します。\n

答え3

awkでこれを行う特別な方法は次のとおりです。

{m,g}awk '((+$_ % 3) % NF)~(!_<NF)' FS='\r$'  # yes that's a 
                                              # tilde ~ not a minus -

1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10

同じことを表現する別の方法

mawk 'NF-!_== (+$+_   %    3    ) % NF' FS='\r$'
gawk 'NF-!_== ( $(_++)%(_+_+_--)) % NF' FS='\r$'

関連情報