删除大部分但不是全部包含回车符 (\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

删除除每三个之外的所有\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$'

相关内容